<!DOCTYPE html>
<html class="has-navbar-fixed-top">
<head><meta name="generator" content="Hexo 3.8.0">
    <meta charset="utf-8">
<title>HANZO</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/outdated-browser/1.1.5/outdatedbrowser.min.css">


<meta name="description" content="鬼王, HANZO, THRAEX">



<meta name="keywords" content="鬼王, O70, HANZO, THRAEX">



    <meta name="description" content="鬼王, HANZO, THRAEX">
<meta name="keywords" content="鬼王, O70, HANZO, THRAEX">
<meta property="og:type" content="website">
<meta property="og:title" content="HANZO">
<meta property="og:url" content="http://yoursite.com/page/6/index.html">
<meta property="og:site_name" content="HANZO">
<meta property="og:description" content="鬼王, HANZO, THRAEX">
<meta property="og:locale" content="en">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="HANZO">
<meta name="twitter:description" content="鬼王, HANZO, THRAEX">





<link rel="icon" href="/images/favicon.ico">


<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Ovo|Source+Code+Pro">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bulma/0.6.2/css/bulma.min.css">


<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/lightgallery/1.6.8/css/lightgallery.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/justifiedGallery/3.6.5/css/justifiedGallery.min.css">


<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css">

<link rel="stylesheet" href="/css/style.css">

<script defer src="//use.fontawesome.com/releases/v5.0.8/js/all.js"></script>



</head>
<body>
    
<nav class="navbar is-transparent is-fixed-top navbar-main" role="navigation" aria-label="main navigation">
    <div class="container">
        <div class="navbar-brand">
            <a class="navbar-item navbar-logo" href="/">
                
                    
                    HANZO
                    
                
            </a>
            <div class="navbar-burger">
                <span></span>
                <span></span>
                <span></span>
            </div>
        </div>
        
        <div class="navbar-menu navbar-start">
            
            <a class="navbar-item " href="/categories/Technology">Technology</a>
            
            <a class="navbar-item " href="/categories/Life">Life</a>
            
            <a class="navbar-item " href="/archives">Archives</a>
            
            <a class="navbar-item " href="/about">About</a>
            
            <a class="navbar-item " href="/main">Main</a>
            
        </div>
        
        <div class="navbar-menu navbar-end">
            
            <a class="navbar-item search" title="Search" href="javascript:;">
                <i class="fas fa-search"></i>
            </a>
            
            
            
            <a class="navbar-item" title="GitHub" href="https://github.com/O70">
                
                <i class="fab fa-github"></i>
                
            </a>
               
            
        </div>
    </div>
</nav>

    <section class="section">
    <div class="container">
    
        <article class="article content gallery" itemscope="" itemprop="blogPost">
    <h1 class="article-title is-size-3 is-size-4-mobile" itemprop="name">
        
            <a href="/documents/others/deploy-test.html" itemprop="url">Deploy Test</a>
        
    </h1>
    <div class="article-meta columns is-variable is-1 is-multiline is-mobile is-size-7-mobile">
        <span class="column is-narrow">
            <time datetime="2018-10-21T01:00:00.000Z" itemprop="datePublished">Oct 21 2018</time>
        </span>
        
        
        <span class="column is-narrow">
            
            
            3 minutes read (About 392 words)
        </span>
        
    </div>
    <div class="article-entry is-size-6-mobile" itemprop="articleBody">
    
        <h1 id="Deploy-Test"><a href="#Deploy-Test" class="headerlink" title="Deploy Test"></a>Deploy Test</h1><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$ scp -r hanzo@10.122.22.115:/home/hanzo/Workspace/MicroServices/esp-framework .</span><br><span class="line">$ scp hanzo@10.122.22.115:/home/hanzo/Workspace/MicroServices/esp-framework/esp-gateway/target/gateway-0.0.1-SNAPSHOT.jar .</span><br><span class="line"></span><br><span class="line">$ scp guiwang@10.122.x.x:common.jar .</span><br></pre></td></tr></table></figure>
<h2 id="Runing-Mode"><a href="#Runing-Mode" class="headerlink" title="Runing Mode"></a>Runing Mode</h2><ul>
<li><p><code>maven</code></p>
<figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ mvn spring-boot:run \</span><br><span class="line">  -DCFG_CONFIG_HOST=10.122.22.115 \</span><br><span class="line">  -Deureka.client.serviceUrl.defaultZone=http://10.122.22.115:8761/eureka</span><br></pre></td></tr></table></figure>
</li>
<li><p><code>java</code></p>
<figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ java -jar gateway-0.0.1-SNAPSHOT.jar \</span><br><span class="line">  --CFG_CONFIG_HOST=10.122.22.115 \</span><br><span class="line">  --eureka.client.serviceUrl.defaultZone=http://10.122.22.115:8761/eureka</span><br></pre></td></tr></table></figure>
</li>
<li><p><code>docker</code></p>
<figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">$ mvn clean package -Dmaven.test.skip=<span class="hljs-literal">true</span> docker:build</span><br><span class="line"></span><br><span class="line">$ docker run -d --name esp-registry -p 8761:8761 10.122.22.115:5000/esp-registry</span><br><span class="line"></span><br><span class="line">$ docker run -d --name esp-config -p 8750:8750 \</span><br><span class="line">  -e CFG_EUREKA_HOST=10.122.22.115 \</span><br><span class="line">  10.122.22.115:5000/esp-config \</span><br><span class="line">  ; docker logs -f esp-gateway</span><br><span class="line"></span><br><span class="line">$ docker run -d --name esp-gateway -p 8765:8765 \</span><br><span class="line">  -e CFG_CONFIG_HOST=10.122.22.115 \</span><br><span class="line">  -e SPRING_CLOUD_CONFIG_LABEL=env \</span><br><span class="line">  10.122.22.115:5000/esp-gateway \</span><br><span class="line">  ; docker logs -f esp-gateway</span><br><span class="line"></span><br><span class="line">$ docker run -d --name esp-admin -p 8085:8085 \</span><br><span class="line">  -e CFG_CONFIG_HOST=10.122.22.115 \</span><br><span class="line">  -e SPRING_CLOUD_CONFIG_LABEL=env \</span><br><span class="line">  10.122.22.115:5000/esp-admin \</span><br><span class="line">  ; docker logs -f esp-admin</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="Docker-Command"><a href="#Docker-Command" class="headerlink" title="Docker Command"></a>Docker Command</h2><ul>
<li><p>Create tag</p>
<figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$ docker tag 10.122.22.115:5000/esp-registry 10.122.22.115:5000/esp-registry</span><br><span class="line">$ docker tag 10.122.22.115:5000/esp-config 10.122.22.115:5000/esp-config</span><br><span class="line">$ docker tag 10.122.22.115:5000/esp-gateway 10.122.22.115:5000/esp-gateway</span><br><span class="line">$ docker tag 10.122.22.115:5000/esp-admin10.122.22.115:5000/esp-admin</span><br></pre></td></tr></table></figure>
</li>
<li><p>Remove container</p>
<figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">$ docker rm -v $(docker stop esp-registry)</span><br><span class="line">$ docker rm -v $(docker stop esp-config)</span><br><span class="line">$ docker rm -v $(docker stop esp-gateway)</span><br><span class="line">$ docker rm -v $(docker stop esp-admin)</span><br><span class="line"><span class="hljs-comment">#! or</span></span><br><span class="line">$ docker ps -a --filter <span class="hljs-string">"name=esp-*"</span></span><br><span class="line">$ docker rm -v $(docker ps -a --filter <span class="hljs-string">"name=esp-*"</span> -q)</span><br></pre></td></tr></table></figure>
</li>
<li><p>Remove image</p>
<figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">$ docker images -f <span class="hljs-string">"reference=10.122.22.115:5000/esp-*"</span></span><br><span class="line"></span><br><span class="line">$ docker rmi $(docker images 10.122.22.115:5000/* -q)</span><br><span class="line"><span class="hljs-comment">#! or</span></span><br><span class="line">$ docker rmi -f $(docker images -f <span class="hljs-string">"reference=10.122.22.115:5000/esp-*"</span> -q)</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="Docker-Settings"><a href="#Docker-Settings" class="headerlink" title="Docker Settings"></a>Docker Settings</h2><ul>
<li><p>/etc/systemd/system/docker.service.d/http-proxy.conf</p>
<figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">[Service]</span><br><span class="line">Environment=&quot;HTTP_PROXY=http://proxy1.bj.petrochina:8080&quot;</span><br><span class="line">Environment=&quot;HTTPS_PROXY=http://proxy1.bj.petrochina:8080&quot; &quot;NO_PROXY=localhost, 127.0.0.1, 10.27.213.66, 10.27.213.69, 10.122.22.115&quot;</span><br></pre></td></tr></table></figure>
</li>
<li><p>/etc/docker/daemon.json</p>
<figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  &quot;registry-mirrors&quot;: [&quot;https://ik8akj45.mirror.aliyuncs.com&quot;],</span><br><span class="line">  &quot;insecure-registries&quot;: [&quot;10.27.213.66:5000&quot;, &quot;10.122.22.115:5000&quot;]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>/var/lib/docker/containers/CONTAINER_ID/hostconfig.json</p>
<figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># update port mapping</span><br><span class="line">&#123;</span><br><span class="line">  ...</span><br><span class="line">  &quot;PortBindings&quot;:&#123;&quot;5000/tcp&quot;:[&#123;&quot;HostIp&quot;:&quot;&quot;,&quot;HostPort&quot;:&quot;5000&quot;&#125;]&#125;</span><br><span class="line">  ...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>http: server gave HTTP response to HTTPS client</p>
<figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">$ vim /etc/docker/daemon.json</span><br><span class="line">&#123;</span><br><span class="line">  <span class="hljs-string">"insecure-registries"</span>:[<span class="hljs-string">"10.122.22.115:5000"</span>]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">$ sudo systemctl daemon-reload</span><br><span class="line">$ sudo systemctl restart docker</span><br></pre></td></tr></table></figure>
</li>
<li><p>net/http: request canceled (Client.Timeout exceeded while awaiting headers)</p>
<figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">$ vim /etc/docker/daemon.json</span><br><span class="line">&#123;</span><br><span class="line">  <span class="hljs-string">"registry-mirrors"</span>: [<span class="hljs-string">"https://ik8akj45.mirror.aliyuncs.com"</span>]</span><br><span class="line">  <span class="hljs-comment"># "registry-mirrors":["https://docker.mirrors.ustc.edu.cn"]</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>On Windows10</p>
<figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  &quot;registry-mirrors&quot;: [</span><br><span class="line">    &quot;https://ik8akj45.mirror.aliyuncs.com&quot;</span><br><span class="line">  ],</span><br><span class="line">  &quot;insecure-registries&quot;: [</span><br><span class="line">    &quot;10.122.163.216:5000&quot;</span><br><span class="line">  ],</span><br><span class="line">  &quot;debug&quot;: true,</span><br><span class="line">  &quot;experimental&quot;: false</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="Questions"><a href="#Questions" class="headerlink" title="Questions"></a>Questions</h2><ul>
<li>spring.cloud.client.ip-address[10.27.213.167/172.16.81.167]</li>
<li>spring.cloud.client.ip-address[10.27.213.167/172.16.81.167]</li>
</ul>

    
    </div>
    
    
</article>





    
        <article class="article content gallery" itemscope="" itemprop="blogPost">
    <h1 class="article-title is-size-3 is-size-4-mobile" itemprop="name">
        
            <a href="/documents/others/docker-run-image.html" itemprop="url">Docker Run Image</a>
        
    </h1>
    <div class="article-meta columns is-variable is-1 is-multiline is-mobile is-size-7-mobile">
        <span class="column is-narrow">
            <time datetime="2018-10-21T01:00:00.000Z" itemprop="datePublished">Oct 21 2018</time>
        </span>
        
        
        <span class="column is-narrow">
            
            
            6 minutes read (About 849 words)
        </span>
        
    </div>
    <div class="article-entry is-size-6-mobile" itemprop="articleBody">
    
        <h1 id="Docker-Run-Image"><a href="#Docker-Run-Image" class="headerlink" title="Docker Run Image"></a>Docker Run Image</h1><h2 id="MySQL"><a href="#MySQL" class="headerlink" title="MySQL"></a>MySQL</h2><p>查看MySQL版本：<br><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">$ docker inspect mysql</span><br><span class="line">...</span><br><span class="line"><span class="hljs-string">"Env"</span>: [</span><br><span class="line">    <span class="hljs-string">"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"</span>,</span><br><span class="line">    <span class="hljs-string">"GOSU_VERSION=1.7"</span>,</span><br><span class="line">    <span class="hljs-string">"MYSQL_MAJOR=5.7"</span>,</span><br><span class="line">    <span class="hljs-string">"MYSQL_VERSION=5.7.21-1debian9"</span></span><br><span class="line">],</span><br><span class="line">...</span><br></pre></td></tr></table></figure></p>
<p>運行鏡像：<br><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">$ docker run -d \</span><br><span class="line">  --name c-mysql \</span><br><span class="line">  -p 3306:3306 \</span><br><span class="line">  -v <span class="hljs-variable">$PWD</span>/Dockers/mysql/conf:/etc/mysql/conf.d \</span><br><span class="line">  -v <span class="hljs-variable">$PWD</span>/Dockers/mysql/data:/var/lib/mysql \</span><br><span class="line">  -v <span class="hljs-variable">$PWD</span>/Dockers/mysql/logs:/<span class="hljs-built_in">log</span> \</span><br><span class="line">  -e MYSQL_ROOT_PASSWORD=hanzo \</span><br><span class="line">  mysql:latest</span><br></pre></td></tr></table></figure></p>
<p>進入容器:</p>
<figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker <span class="hljs-built_in">exec</span> -it c-mysql bash</span><br></pre></td></tr></table></figure>
<figure class="highlight sql hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment"># mysql -u root -p</span></span><br><span class="line"><span class="hljs-keyword">select</span> <span class="hljs-keyword">version</span>();</span><br><span class="line"><span class="hljs-keyword">show</span> <span class="hljs-keyword">databases</span></span><br></pre></td></tr></table></figure>
<p>MySQL查看用戶信息：<br><figure class="highlight sql hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">desc mysql.user;</span><br><span class="line"><span class="hljs-keyword">select</span> Host, <span class="hljs-keyword">User</span> <span class="hljs-keyword">from</span> mysql.user;</span><br><span class="line"><span class="hljs-keyword">show</span> <span class="hljs-keyword">grants</span> <span class="hljs-keyword">for</span> <span class="hljs-string">'root'</span>@<span class="hljs-string">'%'</span>;</span><br></pre></td></tr></table></figure></p>
<p><a href="https://www.cnblogs.com/zeroone/articles/2298942.html" target="_blank" rel="noopener">創建用戶</a>：<br><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">#!! CREATE USER 'username'@'host' IDENTIFIED BY 'password';</span></span><br><span class="line">CREATE USER <span class="hljs-string">'hanzo'</span>@<span class="hljs-string">'%'</span> IDENTIFIED BY <span class="hljs-string">'hanzo70'</span>;</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">#!! GRANT privileges ON databasename.tablename TO 'username'@'host'</span></span><br><span class="line">GRANT ALL ON *.* TO <span class="hljs-string">'hanzo'</span>@<span class="hljs-string">'%'</span>;</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">#!! SET PASSWORD FOR 'username'@'host' = PASSWORD('newpassword');</span></span><br><span class="line"><span class="hljs-comment">#!! 如果是当前登陆用户用SET PASSWORD = PASSWORD("newpassword");</span></span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">#!! REVOKE privilege ON databasename.tablename FROM 'username'@'host';</span></span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">#!! DROP USER 'username'@'host';</span></span><br></pre></td></tr></table></figure></p>
<p>e.g.:<br><figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"># update container env for MYSQL_ROOT_PASSWORD</span><br><span class="line">export MYSQL_ROOT_PASSWORD=&quot;&lt;PREFIX&gt;-hanzo&quot;</span><br><span class="line"></span><br><span class="line"># update root password</span><br><span class="line">mysql -u root -p</span><br><span class="line">SET PASSWORD = PASSWORD(&quot;&lt;PREFIX&gt;-hanzo&quot;);</span><br><span class="line"></span><br><span class="line"># update hanzo password</span><br><span class="line">set password for &apos;hanzo&apos;@&apos;%&apos; = password(&quot;&lt;PREFIX&gt;-hanzo70&quot;);</span><br></pre></td></tr></table></figure></p>
<figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">SHOW CREATE TABLE TABLE_NAME;</span><br><span class="line">ALTER DATABASE DB_NAME DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;</span><br><span class="line">ALTER TABLE TABLE_NAME DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;</span><br></pre></td></tr></table></figure>
<p>随机抽取一条数据:<br><figure class="highlight sql hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> tbl_goods</span><br><span class="line"><span class="hljs-keyword">WHERE</span> <span class="hljs-keyword">id</span> &gt;= (<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">FLOOR</span>(<span class="hljs-keyword">RAND</span>() * (<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">MAX</span>(<span class="hljs-keyword">id</span>) <span class="hljs-keyword">FROM</span> tbl_goods)))</span><br><span class="line"><span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> <span class="hljs-keyword">id</span> <span class="hljs-keyword">LIMIT</span> <span class="hljs-number">1</span>;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">update</span> tbl_goods_snapshot s <span class="hljs-keyword">set</span> s.gid = (</span><br><span class="line">    <span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">id</span> <span class="hljs-keyword">FROM</span> tbl_goods <span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> <span class="hljs-keyword">RAND</span>() <span class="hljs-keyword">LIMIT</span> <span class="hljs-number">1</span></span><br><span class="line">);</span><br></pre></td></tr></table></figure></p>
<p><strong>mysqldump</strong>：<br> <figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ docker run --rm -it mysql mysqldump -h 10.27.213.67 -uroot -phanzo h-admin &gt; h-admin.sql</span><br><span class="line"></span><br><span class="line">$ docker <span class="hljs-built_in">exec</span> -it mysql mysqldump -uroot -phanzo h-admin &gt; h_admin.sql</span><br></pre></td></tr></table></figure></p>
 <figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">docker cp riped-admin.sql container_name</span><br><span class="line">create database riped-admin</span><br><span class="line">use riped-admin</span><br><span class="line">source riped-admin.sql</span><br></pre></td></tr></table></figure>
<h2 id="Zipkin"><a href="#Zipkin" class="headerlink" title="Zipkin"></a>Zipkin</h2><p>Create Database and Table:<br><figure class="highlight sql hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">DROP</span> <span class="hljs-keyword">DATABASE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">EXISTS</span> zipkin;</span><br><span class="line"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">DATABASE</span> zipkin;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">EXISTS</span> zipkin_spans (</span><br><span class="line">  <span class="hljs-string">`trace_id_high`</span> <span class="hljs-built_in">BIGINT</span> <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span> <span class="hljs-keyword">DEFAULT</span> <span class="hljs-number">0</span> <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit'</span>,</span><br><span class="line">  <span class="hljs-string">`trace_id`</span> <span class="hljs-built_in">BIGINT</span> <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,</span><br><span class="line">  <span class="hljs-string">`id`</span> <span class="hljs-built_in">BIGINT</span> <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,</span><br><span class="line">  <span class="hljs-string">`name`</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">255</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,</span><br><span class="line">  <span class="hljs-string">`parent_id`</span> <span class="hljs-built_in">BIGINT</span>,</span><br><span class="line">  <span class="hljs-string">`debug`</span> <span class="hljs-built_in">BIT</span>(<span class="hljs-number">1</span>),</span><br><span class="line">  <span class="hljs-string">`start_ts`</span> <span class="hljs-built_in">BIGINT</span> <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'Span.timestamp(): epoch micros used for endTs query and to implement TTL'</span>,</span><br><span class="line">  <span class="hljs-string">`duration`</span> <span class="hljs-built_in">BIGINT</span> <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'Span.duration(): micros used for minDuration and maxDuration query'</span>,</span><br><span class="line">  PRIMARY <span class="hljs-keyword">KEY</span> (<span class="hljs-string">`trace_id_high`</span>, <span class="hljs-string">`trace_id`</span>, <span class="hljs-string">`id`</span>)</span><br><span class="line">) <span class="hljs-keyword">ENGINE</span>=<span class="hljs-keyword">InnoDB</span> ROW_FORMAT=COMPRESSED <span class="hljs-built_in">CHARACTER</span> <span class="hljs-keyword">SET</span>=utf8 <span class="hljs-keyword">COLLATE</span> utf8_general_ci;</span><br><span class="line"><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> zipkin_spans <span class="hljs-keyword">ADD</span> <span class="hljs-keyword">INDEX</span>(<span class="hljs-string">`trace_id_high`</span>, <span class="hljs-string">`trace_id`</span>) <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'for getTracesByIds'</span>;</span><br><span class="line"><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> zipkin_spans <span class="hljs-keyword">ADD</span> <span class="hljs-keyword">INDEX</span>(<span class="hljs-string">`name`</span>) <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'for getTraces and getSpanNames'</span>;</span><br><span class="line"><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> zipkin_spans <span class="hljs-keyword">ADD</span> <span class="hljs-keyword">INDEX</span>(<span class="hljs-string">`start_ts`</span>) <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'for getTraces ordering and range'</span>;</span><br><span class="line"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">EXISTS</span> zipkin_annotations (</span><br><span class="line">  <span class="hljs-string">`trace_id_high`</span> <span class="hljs-built_in">BIGINT</span> <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span> <span class="hljs-keyword">DEFAULT</span> <span class="hljs-number">0</span> <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit'</span>,</span><br><span class="line">  <span class="hljs-string">`trace_id`</span> <span class="hljs-built_in">BIGINT</span> <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span> <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'coincides with zipkin_spans.trace_id'</span>,</span><br><span class="line">  <span class="hljs-string">`span_id`</span> <span class="hljs-built_in">BIGINT</span> <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span> <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'coincides with zipkin_spans.id'</span>,</span><br><span class="line">  <span class="hljs-string">`a_key`</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">255</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span> <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'BinaryAnnotation.key or Annotation.value if type == -1'</span>,</span><br><span class="line">  <span class="hljs-string">`a_value`</span> <span class="hljs-built_in">BLOB</span> <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'BinaryAnnotation.value(), which must be smaller than 64KB'</span>,</span><br><span class="line">  <span class="hljs-string">`a_type`</span> <span class="hljs-built_in">INT</span> <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span> <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'BinaryAnnotation.type() or -1 if Annotation'</span>,</span><br><span class="line">  <span class="hljs-string">`a_timestamp`</span> <span class="hljs-built_in">BIGINT</span> <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'Used to implement TTL; Annotation.timestamp or zipkin_spans.timestamp'</span>,</span><br><span class="line">  <span class="hljs-string">`endpoint_ipv4`</span> <span class="hljs-built_in">INT</span> <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'Null when Binary/Annotation.endpoint is null'</span>,</span><br><span class="line">  <span class="hljs-string">`endpoint_ipv6`</span> <span class="hljs-built_in">BINARY</span>(<span class="hljs-number">16</span>) <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'Null when Binary/Annotation.endpoint is null, or no IPv6 address'</span>,</span><br><span class="line">  <span class="hljs-string">`endpoint_port`</span> <span class="hljs-built_in">SMALLINT</span> <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'Null when Binary/Annotation.endpoint is null'</span>,</span><br><span class="line">  <span class="hljs-string">`endpoint_service_name`</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">255</span>) <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'Null when Binary/Annotation.endpoint is null'</span></span><br><span class="line">) <span class="hljs-keyword">ENGINE</span>=<span class="hljs-keyword">InnoDB</span> ROW_FORMAT=COMPRESSED <span class="hljs-built_in">CHARACTER</span> <span class="hljs-keyword">SET</span>=utf8 <span class="hljs-keyword">COLLATE</span> utf8_general_ci;</span><br><span class="line"><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> zipkin_annotations <span class="hljs-keyword">ADD</span> <span class="hljs-keyword">UNIQUE</span> <span class="hljs-keyword">KEY</span>(<span class="hljs-string">`trace_id_high`</span>, <span class="hljs-string">`trace_id`</span>, <span class="hljs-string">`span_id`</span>, <span class="hljs-string">`a_key`</span>, <span class="hljs-string">`a_timestamp`</span>) <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'Ignore insert on duplicate'</span>;</span><br><span class="line"><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> zipkin_annotations <span class="hljs-keyword">ADD</span> <span class="hljs-keyword">INDEX</span>(<span class="hljs-string">`trace_id_high`</span>, <span class="hljs-string">`trace_id`</span>, <span class="hljs-string">`span_id`</span>) <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'for joining with zipkin_spans'</span>;</span><br><span class="line"><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> zipkin_annotations <span class="hljs-keyword">ADD</span> <span class="hljs-keyword">INDEX</span>(<span class="hljs-string">`trace_id_high`</span>, <span class="hljs-string">`trace_id`</span>) <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'for getTraces/ByIds'</span>;</span><br><span class="line"><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> zipkin_annotations <span class="hljs-keyword">ADD</span> <span class="hljs-keyword">INDEX</span>(<span class="hljs-string">`endpoint_service_name`</span>) <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'for getTraces and getServiceNames'</span>;</span><br><span class="line"><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> zipkin_annotations <span class="hljs-keyword">ADD</span> <span class="hljs-keyword">INDEX</span>(<span class="hljs-string">`a_type`</span>) <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'for getTraces and autocomplete values'</span>;</span><br><span class="line"><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> zipkin_annotations <span class="hljs-keyword">ADD</span> <span class="hljs-keyword">INDEX</span>(<span class="hljs-string">`a_key`</span>) <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'for getTraces and autocomplete values'</span>;</span><br><span class="line"><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> zipkin_annotations <span class="hljs-keyword">ADD</span> <span class="hljs-keyword">INDEX</span>(<span class="hljs-string">`trace_id`</span>, <span class="hljs-string">`span_id`</span>, <span class="hljs-string">`a_key`</span>) <span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'for dependencies job'</span>;</span><br><span class="line"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">EXISTS</span> zipkin_dependencies (</span><br><span class="line">  <span class="hljs-string">`day`</span> <span class="hljs-built_in">DATE</span> <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,</span><br><span class="line">  <span class="hljs-string">`parent`</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">255</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,</span><br><span class="line">  <span class="hljs-string">`child`</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">255</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,</span><br><span class="line">  <span class="hljs-string">`call_count`</span> <span class="hljs-built_in">BIGINT</span>,</span><br><span class="line">  <span class="hljs-string">`error_count`</span> <span class="hljs-built_in">BIGINT</span>,</span><br><span class="line">  PRIMARY <span class="hljs-keyword">KEY</span> (<span class="hljs-string">`day`</span>, <span class="hljs-string">`parent`</span>, <span class="hljs-string">`child`</span>)</span><br><span class="line">) <span class="hljs-keyword">ENGINE</span>=<span class="hljs-keyword">InnoDB</span> ROW_FORMAT=COMPRESSED <span class="hljs-built_in">CHARACTER</span> <span class="hljs-keyword">SET</span>=utf8 <span class="hljs-keyword">COLLATE</span> utf8_general_ci;</span><br></pre></td></tr></table></figure></p>
<p>Run:<br><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">$ docker run -d \</span><br><span class="line">  --name c-zipkin \</span><br><span class="line">  -p 9411:9411 \</span><br><span class="line">  -e STORAGE_TYPE=mysql \</span><br><span class="line">  -e MYSQL_HOST=10.122.163.77 \</span><br><span class="line">  -e MYSQL_TCP_PORT=3306 \</span><br><span class="line">  -e MYSQL_DB=zipkin \</span><br><span class="line">  -e MYSQL_USER=hanzo \</span><br><span class="line">  -e MYSQL_PASS=hanzo70 \</span><br><span class="line">  openzipkin/zipkin:latest</span><br></pre></td></tr></table></figure></p>

    
    </div>
    
    
</article>





    
        <article class="article content gallery" itemscope="" itemprop="blogPost">
    <h1 class="article-title is-size-3 is-size-4-mobile" itemprop="name">
        
            <a href="/documents/others/three-js.html" itemprop="url">Three.js</a>
        
    </h1>
    <div class="article-meta columns is-variable is-1 is-multiline is-mobile is-size-7-mobile">
        <span class="column is-narrow">
            <time datetime="2018-10-08T01:00:00.000Z" itemprop="datePublished">Oct 8 2018</time>
        </span>
        
        
        <span class="column is-narrow">
            
            
            a minute read (About 174 words)
        </span>
        
    </div>
    <div class="article-entry is-size-6-mobile" itemprop="articleBody">
    
        <h1 id="Three-js"><a href="#Three-js" class="headerlink" title="Three.js"></a>Three.js</h1><h2 id="Chapter-1"><a href="#Chapter-1" class="headerlink" title="Chapter 1"></a>Chapter 1</h2><p>渲染器：</p>
<ul>
<li>基于WebGL</li>
<li>基于CSS-3D</li>
<li>基于画板</li>
<li>基于SVG</li>
</ul>
<p>画板和SVG十分消耗CPU资源，而且缺乏对一些功能的支持，比如材质和阴影。</p>
<ul>
<li>Scene</li>
<li>Camera</li>
<li>Renderer</li>
<li>材质</li>
<li>光源</li>
<li>阴影</li>
</ul>
<p>启动简单Web服务器：<br><figure class="highlight py hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python -m SimpleHTTPServer <span class="hljs-number">8080</span></span><br></pre></td></tr></table></figure></p>
<h2 id="Chapter-2"><a href="#Chapter-2" class="headerlink" title="Chapter 2"></a>Chapter 2</h2><p>组件:</p>
<ul>
<li>摄像机，决定屏幕上哪些东西需要渲染</li>
<li>光源，决定材质如何显示以及用于产生阴影</li>
<li>对象，摄像机透视图里主要的渲染对象，e.g.: 方块，球体</li>
</ul>
<p>THREE.Scene method:</p>
<ul>
<li>Add()</li>
<li>Remove()</li>
<li>children</li>
<li>getObjectByName()</li>
<li>traverse()</li>
</ul>
<p>THREE.Scene attribute:</p>
<ul>
<li>fog(雾化)</li>
<li><p>overrideMaterial(材质覆盖)</p>
</li>
<li><p>正交投影摄像机</p>
</li>
<li>透视投影摄像机</li>
</ul>
<h2 id="Chapter-3"><a href="#Chapter-3" class="headerlink" title="Chapter 3"></a>Chapter 3</h2>
    
    </div>
    
    
</article>





    
        <article class="article content gallery" itemscope="" itemprop="blogPost">
    <h1 class="article-title is-size-3 is-size-4-mobile" itemprop="name">
        
            <a href="/documents/others/turing-books.html" itemprop="url">Turing Books</a>
        
    </h1>
    <div class="article-meta columns is-variable is-1 is-multiline is-mobile is-size-7-mobile">
        <span class="column is-narrow">
            <time datetime="2018-07-09T10:45:00.000Z" itemprop="datePublished">Jul 9 2018</time>
        </span>
        
        
        <span class="column is-narrow">
            
            
            a minute read (About 118 words)
        </span>
        
    </div>
    <div class="article-entry is-size-6-mobile" itemprop="articleBody">
    
        <h2 id="Sample-Book-Exchange"><a href="#Sample-Book-Exchange" class="headerlink" title="Sample Book Exchange"></a>Sample Book Exchange</h2><ul>
<li style="list-style: none"><input type="checkbox"> 黑客与画家：硅谷创业之父Paul Graham文集</li>
<li style="list-style: none"><input type="checkbox"> Linux程序设计(第4版)</li>
<li style="list-style: none"><input type="checkbox" checked> MySQL必知必会</li>
<li style="list-style: none"><input type="checkbox"> 信息简史</li>
<li style="list-style: none"><input type="checkbox"> JavaScript高级程序设计（第3版）</li>
<li style="list-style: none"><input type="checkbox"> 深入浅出Node.js</li>
<li style="list-style: none"><input type="checkbox"> 你不知道的JavaScript（中卷）</li>
<li style="list-style: none"><input type="checkbox"> 精通Git（第2版）</li>
<li style="list-style: none"><input type="checkbox"> 你不知道的JavaScript（下卷）</li>
<li style="list-style: none"><input type="checkbox"> 算法图解</li>
<li style="list-style: none"><input type="checkbox"> Java编程思维</li>
<li style="list-style: none"><input type="checkbox"> Tomcat架构解析</li>
<li style="list-style: none"><input type="checkbox"> Node.js实战（第2版）</li>
<li style="list-style: none"><input type="checkbox" checked> OAuth 2实战</li>
<li style="list-style: none"><input type="checkbox"> JSON实战</li>
<li style="list-style: none"><input type="checkbox"> shell脚本实战（第2版）</li>
</ul>

    
    </div>
    
    
</article>





    
        <article class="article content gallery" itemscope="" itemprop="blogPost">
    <h1 class="article-title is-size-3 is-size-4-mobile" itemprop="name">
        
            <a href="/documents/others/gitlab-issues.html" itemprop="url">GitLab Issues</a>
        
    </h1>
    <div class="article-meta columns is-variable is-1 is-multiline is-mobile is-size-7-mobile">
        <span class="column is-narrow">
            <time datetime="2018-06-21T06:30:00.000Z" itemprop="datePublished">Jun 21 2018</time>
        </span>
        
        
        <span class="column is-narrow">
            
            
            a minute read (About 222 words)
        </span>
        
    </div>
    <div class="article-entry is-size-6-mobile" itemprop="articleBody">
    
        <h2 id="Issues-Labels"><a href="#Issues-Labels" class="headerlink" title="Issues Labels"></a>Issues Labels</h2><blockquote>
<p><strong>类型</strong></p>
<ul>
<li>Group Label(推荐)</li>
<li>Project Label</li>
</ul>
</blockquote>
<blockquote>
<p><strong>作用</strong></p>
<ul>
<li>标注<code>Issue</code>优先级</li>
<li>根据<code>Label</code>过滤未关闭的<code>Issue</code></li>
<li>根据每个项目的<code>Board</code>对<code>Issue</code>进行分类</li>
</ul>
</blockquote>
<h2 id="New-Issue"><a href="#New-Issue" class="headerlink" title="New Issue"></a>New Issue</h2><p><strong>Issue默认创建在每个微服务的<code>UI</code>项目中，e.g.: food-ui, training-ui。</strong></p>
<p><strong>创建Issue需要对应相关的微服务。即选中具体项目进行创建Issue</strong></p>
<ul>
<li>Title</li>
<li>Description</li>
<li>Assignee<ul>
<li>一个人直接在下拉框选中</li>
<li>多个人在 <strong>Description</strong> 中<code>@mention</code>, e.g.: @Guiwang @HANZO</li>
</ul>
</li>
<li>Labels，根据<code>issue</code>含义进行添加，可选中多个</li>
</ul>
<h2 id="Issues-Close"><a href="#Issues-Close" class="headerlink" title="Issues Close"></a>Issues Close</h2><blockquote>
<p><strong>Commit Message</strong></p>
<ul>
<li><a href="http://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html" target="_blank" rel="noopener">Commit message 和 Change log 编写指南</a></li>
<li>每个<code>commit message</code>应该尽量清晰明了，仅看行首就知道某次<code>commit</code>的目的</li>
<li>根据<code>commit</code>生成 <strong>Change log</strong></li>
</ul>
</blockquote>
<blockquote>
<p><strong>Close</strong></p>
<ul>
<li>git commit -m ‘close #3’</li>
<li>git commit -m ‘msg. close #3’</li>
<li>git commit -m ‘closes #2, #3, #6’</li>
<li>git commit -m ‘msg. closes #2, #3, #6’</li>
</ul>
</blockquote>
<p><strong>也可手动在GitLab中直接关闭</strong></p>

    
    </div>
    
    
</article>





    
        <article class="article content gallery" itemscope="" itemprop="blogPost">
    <h1 class="article-title is-size-3 is-size-4-mobile" itemprop="name">
        
            <a href="/documents/others/rabbitmq-in-action.html" itemprop="url">RabbitMQ in Action</a>
        
    </h1>
    <div class="article-meta columns is-variable is-1 is-multiline is-mobile is-size-7-mobile">
        <span class="column is-narrow">
            <time datetime="2018-04-06T01:00:00.000Z" itemprop="datePublished">Apr 6 2018</time>
        </span>
        
        
        <span class="column is-narrow">
            
            
            a minute read (About 179 words)
        </span>
        
    </div>
    <div class="article-entry is-size-6-mobile" itemprop="articleBody">
    
        <h2 id="Chapter-2"><a href="#Chapter-2" class="headerlink" title="Chapter 2"></a>Chapter 2</h2><p><strong>Advanced Message Queuing Protocol</strong></p>
<ul>
<li>Exchange</li>
<li>Queue</li>
<li>Bind</li>
</ul>
<p>Method and Parameter:</p>
<ul>
<li>basic.consume()</li>
<li>basic.get()</li>
<li>basic.ack()</li>
<li>auto_ack</li>
<li>basic.reject()</li>
<li>queue.declare([passive])</li>
<li>exchange.declare()</li>
<li>durable, default: false, 服务器重启后是否重建Queue/Exchange</li>
</ul>
<p><strong>routing key</strong></p>
<p>Exchange types:</p>
<ul>
<li>direct, <code>routing key</code>匹配，消息就被投递到对应的队列</li>
<li>fanout, 消息会投递给所有附加在此交换器上的队列</li>
<li>topic, 不同源头的消息到达同一个队列</li>
<li>headers, 匹配消息的<code>header</code>而非<code>routing key</code></li>
</ul>
<p>指定权限控制在<code>vhost</code>or<code>server</code> level。</p>
<p>默认情况下无法幸免服务器重启。</p>
<p><strong>持久化</strong></p>
<ul>
<li>使用持久化性能受影响</li>
<li>持久性消息在RabbitMQ内建集群工作环境下工作的不好</li>
</ul>
<p><strong>Transaction</strong>和<strong>发送方确认模式</strong></p>

    
    </div>
    
    
</article>





    
        <article class="article content gallery" itemscope="" itemprop="blogPost">
    <h1 class="article-title is-size-3 is-size-4-mobile" itemprop="name">
        
            <a href="/documents/others/git-command.html" itemprop="url">Git Command</a>
        
    </h1>
    <div class="article-meta columns is-variable is-1 is-multiline is-mobile is-size-7-mobile">
        <span class="column is-narrow">
            <time datetime="2018-01-21T01:00:00.000Z" itemprop="datePublished">Jan 21 2018</time>
        </span>
        
        
        <span class="column is-narrow">
            
            
            2 minutes read (About 348 words)
        </span>
        
    </div>
    <div class="article-entry is-size-6-mobile" itemprop="articleBody">
    
        <h1 id="Git-Command"><a href="#Git-Command" class="headerlink" title="Git Command"></a>Git Command</h1><h4 id="Restore-files"><a href="#Restore-files" class="headerlink" title="Restore files"></a>Restore files</h4><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$ get checkout HEAD &lt;filename&gt;</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">#! discard changes in working directory</span></span><br><span class="line">$ get checkout -- &lt;filename&gt;</span><br></pre></td></tr></table></figure>
<h4 id="Show-all-branches"><a href="#Show-all-branches" class="headerlink" title="Show all branches"></a>Show all branches</h4><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git branch -a</span><br></pre></td></tr></table></figure>
<h4 id="Create-a-local-tracking-branch"><a href="#Create-a-local-tracking-branch" class="headerlink" title="Create a local-tracking branch"></a>Create a local-tracking branch</h4><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">#! git branch &lt;branchname&gt; [&lt;start-point&gt;]</span></span><br><span class="line">$ git branch &lt;branchname&gt; &lt;origin/branch_name&gt;</span><br><span class="line">$ git checkout &lt;branchname&gt;</span><br></pre></td></tr></table></figure>
<p>Combined into a single step with:<br><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git checkout -b &lt;branchname&gt; &lt;origin/branch_name&gt;</span><br></pre></td></tr></table></figure></p>
<h4 id="Rename-branch"><a href="#Rename-branch" class="headerlink" title="Rename branch"></a>Rename branch</h4><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git branch -m &lt;oldname&gt; &lt;newname&gt;</span><br></pre></td></tr></table></figure>
<p>Rename a remote-tacking branch and the corresponding reflog:<br><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ git branch -m &lt;oldbranch&gt; &lt;newbranch&gt;</span><br><span class="line">$ git push origin :&lt;oldbranch&gt;</span><br><span class="line">$ git push origin &lt;newbranch&gt;</span><br></pre></td></tr></table></figure></p>
<h4 id="Add-remote-repository"><a href="#Add-remote-repository" class="headerlink" title="Add remote repository"></a>Add remote repository</h4><p>Push an existing repository from the command line:<br><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ git remote add &lt;originname&gt; &lt;url&gt;</span><br><span class="line">$ git push -u &lt;originname&gt; &lt;branchname&gt;</span><br></pre></td></tr></table></figure></p>
<figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git branch --<span class="hljs-built_in">set</span>-upstream-to=origin/&lt;branchname&gt; &lt;localbranchname&gt;</span><br></pre></td></tr></table></figure>
<h4 id="Delete-the-remote-tracking-branch"><a href="#Delete-the-remote-tracking-branch" class="headerlink" title="Delete the remote-tracking branch"></a>Delete the remote-tracking branch</h4><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git push origin --delete &lt;branchname&gt;</span><br></pre></td></tr></table></figure>
<h4 id="Delete-tag"><a href="#Delete-tag" class="headerlink" title="Delete tag"></a>Delete tag</h4><p>Delete existing tags with the given names:<br><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git tag -d &lt;tagname&gt;...</span><br></pre></td></tr></table></figure></p>
<p>Delete remote tag:<br><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">$ git push origin master :refs/tags/&lt;tagname&gt;</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">#! After Git v1.7.0</span></span><br><span class="line">$ git push origin --delete tag &lt;tagname&gt;</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">#! Push an empty branch to the remote branch</span></span><br><span class="line">$ git push origin :&lt;branchname&gt;</span><br></pre></td></tr></table></figure></p>
<h4 id="Local-tag-push-to-remote"><a href="#Local-tag-push-to-remote" class="headerlink" title="Local tag push to remote"></a>Local tag push to remote</h4><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git push origin master --tags</span><br></pre></td></tr></table></figure>
<h4 id="Get-remote-tag"><a href="#Get-remote-tag" class="headerlink" title="Get remote tag"></a>Get remote tag</h4><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git fetch origin tag &lt;tagname&gt;</span><br></pre></td></tr></table></figure>
<h4 id="Version-back"><a href="#Version-back" class="headerlink" title="Version back"></a>Version back</h4><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ git reset --hard &lt;commit&gt;</span><br><span class="line">$ git push -f</span><br></pre></td></tr></table></figure>
<h4 id="Squashed-commits"><a href="#Squashed-commits" class="headerlink" title="Squashed commits"></a>Squashed commits</h4><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">$ git checkout master</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">#! 执行一下命令后，dev上的所有提交已经合并到当前工作区并暂存，但还没有作为一个提交</span></span><br><span class="line">$ git merge --squash dev</span><br><span class="line"></span><br><span class="line">$ git commit –m <span class="hljs-string">'something from dev'</span></span><br></pre></td></tr></table></figure>
<h4 id="Delete-untracked-files"><a href="#Delete-untracked-files" class="headerlink" title="Delete untracked files"></a>Delete untracked files</h4><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ git clean -nfd</span><br><span class="line">$ git clean -fd</span><br></pre></td></tr></table></figure>
<ul>
<li><code>-f, --force</code></li>
<li><code>-d</code>: Remove untracked directories in addition to untracked files</li>
</ul>
<h4 id="Modify-commit-message"><a href="#Modify-commit-message" class="headerlink" title="Modify commit message"></a>Modify commit message</h4><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">$ git stash</span><br><span class="line">$ git rebase HEAD^ --interactive</span><br><span class="line">$ git commit –amend</span><br><span class="line">$ git rebase –<span class="hljs-built_in">continue</span></span><br><span class="line">$ git push -f</span><br></pre></td></tr></table></figure>
<h4 id="Clone-a-specific-branch-or-tag"><a href="#Clone-a-specific-branch-or-tag" class="headerlink" title="Clone a specific branch or tag"></a>Clone a specific branch or tag</h4><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git <span class="hljs-built_in">clone</span> --branch=v2.0.2.RELEASE https://github.com/spring-cloud/spring-cloud-netflix.git</span><br></pre></td></tr></table></figure>
<h4 id="Rebase-commit"><a href="#Rebase-commit" class="headerlink" title="Rebase commit"></a>Rebase commit</h4><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ git checkout master</span><br><span class="line">$ git rebase dev</span><br><span class="line">$ git push --force</span><br></pre></td></tr></table></figure>
<h3 id="Merge-Commits"><a href="#Merge-Commits" class="headerlink" title="Merge Commits"></a>Merge Commits</h3><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ git rebase -i &lt;commit_id&gt;</span><br><span class="line">...pick to squash</span><br><span class="line">$ git push -f</span><br></pre></td></tr></table></figure>
<h3 id="sparse-checkout"><a href="#sparse-checkout" class="headerlink" title="sparse-checkout"></a>sparse-checkout</h3><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">$ mkdir sparses; <span class="hljs-built_in">cd</span> sparses; git init</span><br><span class="line">$ git config core.sparsecheckout <span class="hljs-literal">true</span></span><br><span class="line">$ <span class="hljs-built_in">echo</span> <span class="hljs-string">'FOLDER_NAME'</span> &gt;&gt; .git/info/sparse-checkout</span><br><span class="line">$ git remote add -f origin &lt;repository&gt;</span><br><span class="line">$ git pull --depth=1 origin master</span><br></pre></td></tr></table></figure>

    
    </div>
    
    
</article>





    
        <article class="article content gallery" itemscope="" itemprop="blogPost">
    <h1 class="article-title is-size-3 is-size-4-mobile" itemprop="name">
        
            <a href="/documents/others/git-flow.html" itemprop="url">Git Flow</a>
        
    </h1>
    <div class="article-meta columns is-variable is-1 is-multiline is-mobile is-size-7-mobile">
        <span class="column is-narrow">
            <time datetime="2018-01-21T01:00:00.000Z" itemprop="datePublished">Jan 21 2018</time>
        </span>
        
        
        <span class="column is-narrow">
            
            
            6 minutes read (About 875 words)
        </span>
        
    </div>
    <div class="article-entry is-size-6-mobile" itemprop="articleBody">
    
        <h1 id="Git-Flow"><a href="#Git-Flow" class="headerlink" title="Git Flow"></a>Git Flow</h1><p><strong>约定:</strong></p>
<blockquote>
<ul>
<li>任何开发人员只能通过变基提交向<code>master</code>分支推送代码</li>
<li><code>master</code>分支每个提交必需打上标签(<code>Tag</code>)</li>
<li>测试/产品部署基于<code>dev</code>分支</li>
<li>新功能(模块)分支基于<code>dev</code>分支，命名为<code>feature/MODULE_NAME</code></li>
<li>Bug分支给予<code>dev</code>分支，命名为<code>bug/BUG_NAME</code></li>
</ul>
</blockquote>
<h3 id="基本范例"><a href="#基本范例" class="headerlink" title="基本范例"></a>基本范例</h3><p><strong>使用不同的<code>Git</code>命令组合或<code>GitLab</code>操作往往可以达到相同目的。</strong></p>
<p>当前范例从新建项目开始，已存在的项目相关操作也在其中。</p>
<h4 id="1-创建项目并建立dev分支"><a href="#1-创建项目并建立dev分支" class="headerlink" title="1.  创建项目并建立dev分支"></a>1.  创建项目并建立<code>dev</code>分支</h4><p>在<code>GitLab</code>上创建项目(<code>git-notes</code>)。<br>直接在<code>GitLab</code>上添加<code>README.md</code>文件，创建<code>master</code>分支的第一个提交<code>Initial commit</code>。</p>
<p>创建<code>dev</code>分支：</p>
<figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">git clone REPO_URL/git-notes</span><br><span class="line">git checkout -b dev #^创建并检出dev分支</span><br><span class="line">git branch -a #^查看所有分支</span><br><span class="line">git push -u origin dev #^新建远程追踪分支，保持本地与远程可同步</span><br></pre></td></tr></table></figure>
<p>当然可以直接在<code>GitLab</code>上新建<code>dev</code>分支，简单而直接。在之后的克隆可以如下操作：</p>
<figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git clone REPO_URL/git-notes</span><br><span class="line">git checkout -b dev origin/dev #^建立并启动本地分支dev，用于追踪远程分支origin/dev</span><br></pre></td></tr></table></figure>
<h4 id="2-开发新功能"><a href="#2-开发新功能" class="headerlink" title="2. 开发新功能"></a>2. 开发新功能</h4><p>e.g.: A和B开始开发新功能</p>
<p>A:<br><figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">git checkout -b feature/admin dev</span><br><span class="line">git status</span><br><span class="line">git add .</span><br><span class="line">git commit -m &apos;feat(admin): 添加基本服務&apos;</span><br><span class="line"></span><br><span class="line">git checkout dev</span><br><span class="line">git pull</span><br><span class="line"></span><br><span class="line">git merge feature/admin #^合并本地功能分支feature/admin至本地dev分支</span><br><span class="line">git push</span><br></pre></td></tr></table></figure></p>
<p>B:<br><figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">git checkout -b feature/admin_ui dev</span><br><span class="line">git status</span><br><span class="line">git add .</span><br><span class="line">git commit -m &apos;feat(Admin-UI): 添加後台管理UI&apos;</span><br><span class="line"></span><br><span class="line">git checkout dev</span><br><span class="line">git pull</span><br><span class="line"></span><br><span class="line">git merge feature/admin_ui</span><br><span class="line">git push</span><br></pre></td></tr></table></figure></p>
<p><strong>关于提交消息请阅读<a href="http://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html" target="_blank" rel="noopener">Commit message 和 Change log 编写指南</a></strong></p>
<p>操作到现在，功能分支仅存在于本地。依据目前规则，测试/产品部署基于<code>dev</code>分支代码，所以不是所有功能分支的代码都能够及时合并到本地<code>dev</code>分支，并推送至远程<code>origin/dev</code>分支上。但本地功能分支代码又不能仅存放于本地，可将本地功能分支推送至<code>GitLab</code>，如下操作，以A为例：</p>
<figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git checkout feature/admin</span><br><span class="line">git push -u origin feature/admin</span><br></pre></td></tr></table></figure>
<p>远程仓库建立分支<code>feature/admin</code>，与本地分支<code>feature/admin</code>相对应，往后的操作(pull/push)都可以一直基于此分支。<br>当然如果需要合并代码至<code>dev</code>分支，还是和上述操作一样。</p>
<p>在功能开发完毕之后，所有代码都合并到了<code>dev</code>分支上，需要删除无用的功能分支。</p>
<figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git push --delete origin feature/admin #^删除远程仓库中的feature/admin分支</span><br><span class="line">git branch --unset-upstream feature/admin #^从.git/config文件中去除相应配置</span><br><span class="line">git branch -d feature/admin #^删除本地feature/admin分支</span><br></pre></td></tr></table></figure>
<p><strong>修改Bug也需要创建分支(<code>bug/BUG_NAME</code>)，操作与开发新功能类似。</strong></p>
<h4 id="3-合并代码至master"><a href="#3-合并代码至master" class="headerlink" title="3. 合并代码至master"></a>3. 合并代码至<code>master</code></h4><p>测试/产品部署基于<code>dev</code>分支，完成之后，合并<code>dev</code>分支代码至<code>master</code>，并打上<code>Tag</code>：</p>
<p>分支开发完成后，很可能有一堆commit，但是合并到主干的时候，往往希望只有一个（或最多两三个）commit，这样不仅清晰，也容易管理。</p>
<figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">git checkout master</span><br><span class="line">git merge dev</span><br><span class="line">git rebase -i HEAD~2 #^https://git-scm.com/book/zh/v1/Git-工具-重写历史</span><br><span class="line">git tag v0.1</span><br><span class="line">git push</span><br><span class="line">git push origin v0.1</span><br></pre></td></tr></table></figure>

    
    </div>
    
    
</article>





    
        <article class="article content gallery" itemscope="" itemprop="blogPost">
    <h1 class="article-title is-size-3 is-size-4-mobile" itemprop="name">
        
            <a href="/documents/others/github-gitee-pages-hexo.html" itemprop="url">GitHub/Gitee Pages + Hexo</a>
        
    </h1>
    <div class="article-meta columns is-variable is-1 is-multiline is-mobile is-size-7-mobile">
        <span class="column is-narrow">
            <time datetime="2018-01-21T01:00:00.000Z" itemprop="datePublished">Jan 21 2018</time>
        </span>
        
        
        <span class="column is-narrow">
            
            
            2 minutes read (About 230 words)
        </span>
        
    </div>
    <div class="article-entry is-size-6-mobile" itemprop="articleBody">
    
        <h1 id="GitHub-Gitee-Pages-Hexo"><a href="#GitHub-Gitee-Pages-Hexo" class="headerlink" title="GitHub/Gitee Pages + Hexo"></a>GitHub/Gitee Pages + Hexo</h1><h2 id="Requirements"><a href="#Requirements" class="headerlink" title="Requirements"></a>Requirements</h2><ul>
<li>Node.js</li>
<li>Git</li>
</ul>
<h2 id="Install-Hexo"><a href="#Install-Hexo" class="headerlink" title="Install Hexo:"></a>Install Hexo:</h2><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">$ npm install -g hexo-cli</span><br><span class="line">$ npm ls -g --depth=0</span><br><span class="line">/usr/<span class="hljs-built_in">local</span>/lib</span><br><span class="line">├── hexo-cli@1.1.0</span><br><span class="line">└── npm@6.4.1</span><br></pre></td></tr></table></figure>
<p>若出现<code>permission denied</code>,请在命令前加<code>sudo</code>。</p>
<h2 id="新建一个网站"><a href="#新建一个网站" class="headerlink" title="新建一个网站"></a>新建一个网站</h2><p><a href="https://hexo.io/zh-cn/docs/setup" target="_blank" rel="noopener">官网</a>给出以下一套命令进行建站。</p>
<figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$ hexo init &lt;folder&gt;</span><br><span class="line">$ <span class="hljs-built_in">cd</span> &lt;folder&gt;</span><br><span class="line"></span><br><span class="line">$ npm install</span><br></pre></td></tr></table></figure>
<p>在当前版本的<code>hexo-cli</code>，<code>npm install</code>不需要执行，在<code>init</code>的时候会安装相应的依赖。</p>
<h2 id="启动服务器"><a href="#启动服务器" class="headerlink" title="启动服务器"></a>启动服务器</h2><figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo server</span><br></pre></td></tr></table></figure>
<p>默认情况下，访问网址为： <a href="http://localhost:4000。" target="_blank" rel="noopener">http://localhost:4000。</a></p>
<h2 id="Theme"><a href="#Theme" class="headerlink" title="Theme"></a>Theme</h2><p>默认主题存放于<code>&lt;folder&gt;/themes</code>下，为<code>landscape</code>。你可以从<a href="https://hexo.io/themes/" target="_blank" rel="noopener">主题列表</a>中挑选自己喜欢的主题，下载并替换。</p>
<ul>
<li><p>下载</p>
<figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="hljs-built_in">cd</span> themes/</span><br><span class="line">$ git <span class="hljs-built_in">clone</span> https://github.com/probberechts/hexo-theme-cactus.git</span><br><span class="line">$ rm -rf landscape/</span><br></pre></td></tr></table></figure>
</li>
<li><p>修改<code>_config.yml</code>文件:</p>
<figure class="highlight yaml hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-attr">theme:</span> <span class="hljs-string">hexo-theme-cactus</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>重新启动服务器进行预览</p>
<figure class="highlight bash hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo server</span><br></pre></td></tr></table></figure>
</li>
</ul>
<!-- [hexo-theme-doc](https://zalando-incubator.github.io/hexo-theme-doc/) -->

    
    </div>
    
    
</article>





    
        <article class="article content gallery" itemscope="" itemprop="blogPost">
    <h1 class="article-title is-size-3 is-size-4-mobile" itemprop="name">
        
            <a href="/documents/others/you-dont-t-know-javascript.html" itemprop="url">You Dont&#39;t Know JavaScript</a>
        
    </h1>
    <div class="article-meta columns is-variable is-1 is-multiline is-mobile is-size-7-mobile">
        <span class="column is-narrow">
            <time datetime="2018-01-19T01:00:00.000Z" itemprop="datePublished">Jan 19 2018</time>
        </span>
        
        
        <span class="column is-narrow">
            
            
            an hour read (About 6971 words)
        </span>
        
    </div>
    <div class="article-entry is-size-6-mobile" itemprop="articleBody">
    
        <h1 id="目录"><a href="#目录" class="headerlink" title="目录"></a>目录</h1><p>[TOC]</p>
<h1 id="ES"><a href="#ES" class="headerlink" title="ES"></a>ES</h1><p><strong>JavaScript</strong>标准的官方名称是<strong>ECMAScript</strong>，简称<strong>ES</strong>。</p>
<p>最早版本ES1和ES2，实现很少，不怎么为人所知。第一个流行起来的版本是ES3，它成为浏览器IE6-8和早前的旧版Android 2.x移动浏览器的JavaScript标准。出于某些政治原因，倒霉的ES4从来没有成形。</p>
<p>2009年，ES5正式发布(然后是2011年的ES5.1)，在当代浏览器(包括Firefox、Chrome、Opera、Safari以及许多其他类型)的进化和爆发中成为JavaScript广泛使用的标准。</p>
<p>ES6，发布日期从2013年拖到2014年，然后又到2015年。</p>
<p>在ES6之前的JavaScript标准通常被称为ES5(严格说是ES5.1)。</p>
<h2 id="1-作用域"><a href="#1-作用域" class="headerlink" title="1. 作用域"></a>1. 作用域</h2><p><strong>作用域是一套规则，用于确定在何处以及如何查找变量(标识符)。</strong></p>
<p>有两种主要工作模型: <strong>词法作用域</strong>和<strong>动态作用域</strong>。</p>
<p><strong>词法作用域意味着作用域是由书写代码时函数声明的位置来决定的。</strong>是一套关于引擎如何寻找变量及会在何处找到变量的规则。编译的词法分析阶段基本能够知道全部标识符在哪里以及是如何声明的，从而能够预测在执行过程中如何对它们进行查找。</p>
<p>而动态作用域并不关心函数和作用域是如何声明以及在何处声明的，只关心它们从<strong>从何处调用</strong>。</p>
<p>两者之间主要区别:</p>
<ul>
<li>词法作用域是在写代码或者说定义时确定的，而动态作用域是在运行时确定的。</li>
<li>词法作用域关注函数在何处声明，而动态作用域关注函数从何处调用。</li>
</ul>
<h3 id="编译执行"><a href="#编译执行" class="headerlink" title="编译执行"></a>编译执行</h3><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> a = <span class="hljs-number">2</span>;</span><br></pre></td></tr></table></figure>
<ul>
<li><p>编译阶段</p>
<p>  遇到<code>var a</code>，<strong>编译器</strong>会询问<strong>作用域</strong>是否已经有一个该名称的变量存在于同一个作用域的集合中。如果是，编译器会忽略该声明，继续进行编译;否则它会要求作用域在当前作 用域的集合中声明一个新的变量，并命名为<code>a</code>。</p>
</li>
<li><p>执行阶段</p>
<p>  接下来编译器会为<strong>引擎</strong>生成运行时所需的代码，这些代码被用来处理<code>a = 2</code>这个赋值操作。引擎运行时会首先询问作用域，在当前的作用域集合中是否存在一个叫作<code>a</code>的 变量。如果是，引擎就会使用这个变量;如果否，引擎会继续查找该变量。</p>
</li>
</ul>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-meta">'use strict'</span>; <span class="hljs-comment">// ES5引入</span></span><br><span class="line">a = <span class="hljs-number">2</span>;</span><br></pre></td></tr></table></figure>
<p>上述代码对于<code>a = 2</code>，如果<strong>引擎</strong>最终在所有可访问的<strong>词法作用域</strong>中找到了<code>a</code>变量，就会将<code>2</code>赋值给它。否则引擎就会抛出一个<strong>异常</strong>。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params">a</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(a, b); <span class="hljs-comment">// ReferenceError: b is not defined</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">foo(<span class="hljs-number">2</span>);</span><br></pre></td></tr></table></figure>
<p>当获取某个变量的值，在所有<strong>嵌套作用域</strong>中找不到所需变量，引擎就会抛出<strong>ReferenceError</strong>，即作用域判别失败。而<strong>TypeError</strong>则是作用域判别成功了，但是对结果的操作是非法或不合理的。</p>
<h3 id="常见作用域单元"><a href="#常见作用域单元" class="headerlink" title="常见作用域单元"></a>常见作用域单元</h3><ul>
<li><p>函数声明</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> a = <span class="hljs-number">4</span>;</span><br><span class="line"></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">var</span> a = <span class="hljs-number">3</span>;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// 3</span></span><br><span class="line">&#125;</span><br><span class="line">foo();</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// 4</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>匿名函数表达式</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> a = <span class="hljs-number">4</span>;</span><br><span class="line"></span><br><span class="line">setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">var</span> a = <span class="hljs-number">3</span>;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// 3</span></span><br><span class="line">&#125;, <span class="hljs-number">1000</span>);</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// 4</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>具名函数表达式</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">hadnler</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-comment">// ...</span></span><br><span class="line">&#125;, <span class="hljs-number">1000</span>);</span><br></pre></td></tr></table></figure>
</li>
<li><p>立即执行函数表达式</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> a = <span class="hljs-number">4</span>;</span><br><span class="line"></span><br><span class="line">(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">var</span> a = <span class="hljs-number">3</span>;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// 3</span></span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// 4</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>社区规定术语：<strong>IIFE(Immediately Invoked Function Expression)</strong>。最佳实践：<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">IIFE</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-comment">// ...</span></span><br><span class="line">&#125;)();</span><br></pre></td></tr></table></figure></p>
<ul>
<li><strong>块</strong><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">10</span>; i++) &#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(i);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(i); <span class="hljs-comment">// 10</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> t = <span class="hljs-literal">true</span>;</span><br><span class="line"><span class="hljs-keyword">if</span> (t) &#123;</span><br><span class="line">	<span class="hljs-keyword">var</span> a = <span class="hljs-number">3</span>;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(a);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// 3</span></span><br></pre></td></tr></table></figure>
<p>变量的声明应该距离使用的地方越近越好。但是，上述代码中变量<code>i</code>和<code>a</code>，会被绑定在外部作用域(<strong>函数或全局</strong>)(<a href="#提升">提升</a>)，它们只是为了风格而伪装出的形式上的块作用域。为了防止在作用域内被提升，ES6引入了<a href="#let">let</a>关键字。</p>
<h3 id="提升"><a href="#提升" class="headerlink" title="提升"></a>提升</h3><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">a = <span class="hljs-number">2</span>;</span><br><span class="line"><span class="hljs-keyword">var</span> a;</span><br><span class="line"><span class="hljs-built_in">console</span>.log(a);</span><br></pre></td></tr></table></figure>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-built_in">console</span>.log(a);</span><br><span class="line"><span class="hljs-keyword">var</span> a = <span class="hljs-number">2</span>;</span><br></pre></td></tr></table></figure>
<p><strong>变量和函数的所有声明都会在任何代码被执行前首先被处理。</strong>就好像它们在代码中出现的位置被“移动”到了最上面，这个过程就叫<strong>提升</strong>。</p>
<p>So，以上两段代码会以如下形式进行处理：<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> a;</span><br><span class="line">a = <span class="hljs-number">2</span>;</span><br><span class="line"><span class="hljs-built_in">console</span>.log(a);</span><br></pre></td></tr></table></figure></p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> a;</span><br><span class="line"><span class="hljs-built_in">console</span>.log(a);</span><br><span class="line">a = <span class="hljs-number">2</span>;</span><br></pre></td></tr></table></figure>
<blockquote>
<ul>
<li><strong>只有声明本身会被提升，赋值或其他运行逻辑会留在原地，等待被执行。如果提改变了代码的执行顺序，会造成非常严重的破坏</strong></li>
<li><strong>每个作用域都会进行提升操作</strong></li>
<li><strong>函数会优先被提升</strong></li>
</ul>
</blockquote>
<h2 id="2-闭包"><a href="#2-闭包" class="headerlink" title="2. 闭包"></a>2. 闭包</h2><h3 id="识别闭包"><a href="#识别闭包" class="headerlink" title="识别闭包"></a>识别闭包</h3><p>当函数可以记住并访问所在的词法作用域时，就产生了闭包，即使函数是在当前词法作用域之外执行。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">var</span> a = <span class="hljs-number">2</span>;</span><br><span class="line"></span><br><span class="line">	<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bar</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">		<span class="hljs-built_in">console</span>.log(a);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="hljs-keyword">return</span> bar;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> baz = foo();</span><br><span class="line"></span><br><span class="line">baz(); <span class="hljs-comment">// 2 —— 闭包的效果</span></span><br></pre></td></tr></table></figure>
<p>在<code>foo()</code>执行后，通常会期待<code>foo()</code>的整个内部作用域都被销毁，因为引擎有垃回收器用来释放不再使用的内存空间。由于看上去<code>foo()</code>的内容不会再被使用，所以很自然地会考虑对其进行回收。</p>
<p><strong>闭包</strong>的存在使得<code>foo()</code>内部作用域没有被回收。<code>bar()</code>本身在使用内部作用域，它依然持有对该作用域的引用，这个引用就叫“<strong>闭包</strong>”。</p>
<p>无论使用哪种形式对函数类型的值<strong>进行传递</strong>，当函数在别处被调用时，就会产生闭包。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">var</span> a = <span class="hljs-number">2</span>;</span><br><span class="line"></span><br><span class="line">	<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">baz</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">		<span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// 2</span></span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	bar(baz);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bar</span>(<span class="hljs-params">fn</span>) </span>&#123;</span><br><span class="line">	fn(); <span class="hljs-comment">// 闭包</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> fn;</span><br><span class="line"></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">var</span> a = <span class="hljs-number">2</span>;</span><br><span class="line"></span><br><span class="line">	<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">baz</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">		<span class="hljs-built_in">console</span>.log(a);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	fn = baz; <span class="hljs-comment">// 将baz分配给全局变量，间接传递</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bar</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	fn(); <span class="hljs-comment">// 闭包</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">foo();</span><br><span class="line"></span><br><span class="line">bar(); <span class="hljs-comment">// 2</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">wait</span>(<span class="hljs-params">msg</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">var</span> type = <span class="hljs-string">'info:'</span>;</span><br><span class="line"></span><br><span class="line">	setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">timer</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">		<span class="hljs-built_in">console</span>.log(type, msg); <span class="hljs-comment">// info: hello, closure</span></span><br><span class="line">	&#125;, <span class="hljs-number">1000</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">wait(<span class="hljs-string">'hello, closure'</span>);</span><br></pre></td></tr></table></figure>
<h3 id="循环和闭包"><a href="#循环和闭包" class="headerlink" title="循环和闭包"></a>循环和闭包</h3><ul>
<li>共享全局作用域<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">1</span>; i &lt;= <span class="hljs-number">5</span>; i++) &#123;</span><br><span class="line">	setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">timer</span>(<span class="hljs-params"></span>) </span>&#123; <span class="hljs-comment">// timer会在循环结束时才执行</span></span><br><span class="line">		<span class="hljs-built_in">console</span>.log(i);</span><br><span class="line">	&#125;, i*<span class="hljs-number">1000</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>理想情况是循环中的每个迭代在运行时都会给自己“捕获”一个<code>i</code>的副本。但是根据作用域的工作原理，尽管五个函数是在各个迭代中分别定义的，但其实它们都<strong>被封闭在一个共享的全局作用域中</strong>，因此实际上只有一个<code>i</code>。</p>
<ul>
<li><p>每个迭代创建一个闭包作用域</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">1</span>; i &lt;= <span class="hljs-number">5</span>; i++) &#123;</span><br><span class="line">	(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">		<span class="hljs-keyword">var</span> j = i;</span><br><span class="line">		setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">timer</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">			<span class="hljs-built_in">console</span>.log(j);</span><br><span class="line">		&#125;, j*<span class="hljs-number">1000</span>);</span><br><span class="line">	&#125;)();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">// 改进版</span></span><br><span class="line"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">1</span>; i &lt;= <span class="hljs-number">5</span>; i++) &#123;</span><br><span class="line">	(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">j</span>) </span>&#123;</span><br><span class="line">		setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">timer</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">			<span class="hljs-built_in">console</span>.log(j);</span><br><span class="line">		&#125;, j*<span class="hljs-number">1000</span>);</span><br><span class="line">	&#125;)(i);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>使用块作用域</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">1</span>; i &lt;= <span class="hljs-number">5</span>; i++) &#123;</span><br><span class="line">	setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">timer</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">		<span class="hljs-built_in">console</span>.log(i);</span><br><span class="line">	&#125;, i*<span class="hljs-number">1000</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="模块"><a href="#模块" class="headerlink" title="模块"></a>模块</h3><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">CoolModule</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">var</span> something = <span class="hljs-string">"cool"</span>;</span><br><span class="line">	<span class="hljs-keyword">var</span> another = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];</span><br><span class="line"></span><br><span class="line">	<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">doSomething</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">		<span class="hljs-built_in">console</span>.log(something);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">doAnother</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">		<span class="hljs-built_in">console</span>.log(another.join(<span class="hljs-string">" ! "</span>));</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="hljs-keyword">return</span> &#123;</span><br><span class="line">		doSomething: doSomething,</span><br><span class="line">		doAnother: doAnother</span><br><span class="line">	&#125;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> foo = CoolModule();</span><br><span class="line"></span><br><span class="line">foo.doSomething(); <span class="hljs-comment">// cool</span></span><br><span class="line">foo.doAnother(); <span class="hljs-comment">// 1 ! 2 ! 3</span></span><br></pre></td></tr></table></figure>
<p>以上模式在JavaScript中被称为<strong>模块</strong>。最常见的实现模块模式的方法通常被称为<strong>模块暴露</strong>，这里展示的是其变体。</p>
<p>模块模式需要具备两个<strong>必要条件</strong>：</p>
<ul>
<li>必须有外部的封闭函数，该函数必须至少被调用一次(每次调用都会创建一个新的模块实例)。</li>
<li>封闭函数必须返回至少一个内部函数，这样内部函数才能在私有作用域中形成闭包，并且可以访问或者修改私有的状态。</li>
</ul>
<p>上一段代码中有一个叫作<code>CoolModule()</code>的独立的模块创建器，可以被调用任意多次，每次调用都会创建一个新的模块实例。当只需要一个实例时，可以对这个模式进行简单的改进来实现<strong>单例模式</strong>:<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> foo = (<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">CoolModule</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">var</span> something = <span class="hljs-string">"cool"</span>;</span><br><span class="line">	<span class="hljs-keyword">var</span> another = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];</span><br><span class="line"></span><br><span class="line">	<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">doSomething</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">		<span class="hljs-built_in">console</span>.log(something);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">doAnother</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">		<span class="hljs-built_in">console</span>.log(another.join(<span class="hljs-string">" ! "</span>));</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="hljs-keyword">return</span> &#123;</span><br><span class="line">		doSomething: doSomething,</span><br><span class="line">		doAnother: doAnother</span><br><span class="line">	&#125;;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line">foo.doSomething(); <span class="hljs-comment">// cool</span></span><br><span class="line">foo.doAnother(); <span class="hljs-comment">// 1 ! 2 ! 3</span></span><br></pre></td></tr></table></figure></p>
<h4 id="现代模块机制"><a href="#现代模块机制" class="headerlink" title="现代模块机制"></a>现代模块机制</h4><p>模块加载器/管理器：<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> MyModules = (<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Manager</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">var</span> modules = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">	<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">define</span>(<span class="hljs-params">name, deps, impl</span>) </span>&#123;</span><br><span class="line">		<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; deps.length; i++) &#123;</span><br><span class="line">			deps[i] = modules[deps[i]];</span><br><span class="line">		&#125;</span><br><span class="line">		modules[name] = impl.apply(impl, deps); <span class="hljs-comment">// 核心</span></span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">get</span>(<span class="hljs-params">name</span>) </span>&#123;</span><br><span class="line">		<span class="hljs-keyword">return</span> modules[name];</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="hljs-keyword">return</span> &#123;</span><br><span class="line">		define: define,</span><br><span class="line">		get: get</span><br><span class="line">	&#125;;</span><br><span class="line">&#125;)();</span><br></pre></td></tr></table></figure></p>
<p>定义模块：<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">MyModules.define( <span class="hljs-string">"bar"</span>, [], <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">hello</span>(<span class="hljs-params">who</span>) </span>&#123;</span><br><span class="line">		<span class="hljs-keyword">return</span> <span class="hljs-string">"Let me introduce: "</span> + who;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="hljs-keyword">return</span> &#123;</span><br><span class="line">		hello: hello</span><br><span class="line">	&#125;;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">MyModules.define( <span class="hljs-string">"foo"</span>, [<span class="hljs-string">"bar"</span>], <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">bar</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">var</span> hungry = <span class="hljs-string">"hippo"</span>;</span><br><span class="line"></span><br><span class="line">	<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">awesome</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">		<span class="hljs-built_in">console</span>.log(bar.hello( hungry ).toUpperCase());</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="hljs-keyword">return</span> &#123;</span><br><span class="line">		awesome: awesome</span><br><span class="line">	&#125;;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> bar = MyModules.get( <span class="hljs-string">"bar"</span> );</span><br><span class="line"><span class="hljs-keyword">var</span> foo = MyModules.get( <span class="hljs-string">"foo"</span> );</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(bar.hello( <span class="hljs-string">"hippo"</span> )); <span class="hljs-comment">// Let me introduce: hippo</span></span><br><span class="line"></span><br><span class="line">foo.awesome(); <span class="hljs-comment">// LET ME INTRODUCE: HIPPO</span></span><br></pre></td></tr></table></figure></p>
<h4 id="未来模块机制"><a href="#未来模块机制" class="headerlink" title="未来模块机制"></a>未来模块机制</h4><ul>
<li><p>bar.js</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">hello</span>(<span class="hljs-params">who</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">return</span> <span class="hljs-string">"Let me introduce: "</span> + who;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">export</span> hello;</span><br></pre></td></tr></table></figure>
</li>
<li><p>foo.js</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">// 仅从 "bar" 模块导入 hello()</span></span><br><span class="line"><span class="hljs-keyword">import</span> hello <span class="hljs-keyword">from</span> <span class="hljs-string">"bar"</span>;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> hungry = <span class="hljs-string">"hippo"</span>;</span><br><span class="line"></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">awesome</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(hello(hungry).toUpperCase());</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">export</span> awesome;</span><br></pre></td></tr></table></figure>
</li>
<li><p>baz.js</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-built_in">module</span> foo <span class="hljs-keyword">from</span> <span class="hljs-string">"foo"</span>;</span><br><span class="line"><span class="hljs-built_in">module</span> bar <span class="hljs-keyword">from</span> <span class="hljs-string">"bar"</span>;</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(bar.hello(<span class="hljs-string">"rhino"</span>)); <span class="hljs-comment">// Let me introduce: rhino</span></span><br><span class="line"></span><br><span class="line">foo.awesome(); <span class="hljs-comment">// LET ME INTRODUCE: HIPPO</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="3-this"><a href="#3-this" class="headerlink" title="3. this"></a>3. this</h2><p><code>this</code>可以优雅的隐式“传递”一个对象引用，让API设计的更加简洁并且易于使用。如果显示传递上下文对象会让代码变的越来越混乱。</p>
<p><code>this</code>是在运行时进行绑定的，并不是在编写时绑定，它的上下文取决于函数调用时的各种条件。<code>this</code>的绑定和函数声明的位置没有任何关系，只取决于函数的调用方式。</p>
<p>当一个函数被调用时，会创建一个活动记录(有时候也称为执行上下文)。这个记录会包含函数在哪里被调用(调用栈)、函数的调用方法、传入的参数等信息。<code>this</code>就是记录的 其中一个属性，会在函数执行的过程中用到。</p>
<h3 id="误解"><a href="#误解" class="headerlink" title="误解"></a>误解</h3><h4 id="指向函数自身"><a href="#指向函数自身" class="headerlink" title="指向函数自身"></a>指向函数自身</h4><p>记录函数<code>foo</code>的被调用次数：<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params">num</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"foo: "</span> + num);</span><br><span class="line"></span><br><span class="line">	<span class="hljs-comment">// 记录 foo 被调用的次数</span></span><br><span class="line">	<span class="hljs-keyword">this</span>.count++;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">foo.count = <span class="hljs-number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> i;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">10</span>; i++) &#123;</span><br><span class="line">	<span class="hljs-keyword">if</span> (i &gt; <span class="hljs-number">5</span>) &#123; foo(i); &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(foo.count); <span class="hljs-comment">// 0</span></span><br><span class="line"><span class="hljs-built_in">console</span>.log(count); <span class="hljs-comment">// NaN</span></span><br></pre></td></tr></table></figure></p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params">num</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"foo: "</span> + num);</span><br><span class="line"></span><br><span class="line">	<span class="hljs-comment">// 记录 foo 被调用的次数</span></span><br><span class="line">	<span class="hljs-keyword">this</span>.count++;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">foo.count = <span class="hljs-number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> i;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">10</span>; i++) &#123;</span><br><span class="line">	<span class="hljs-keyword">if</span> (i &gt; <span class="hljs-number">5</span>) &#123;</span><br><span class="line">		<span class="hljs-comment">// 使用 call(..) 可以确保 this 指向函数对象 foo 本身</span></span><br><span class="line">		foo.call(foo, i);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(foo.count); <span class="hljs-comment">// 4</span></span><br></pre></td></tr></table></figure>
<h4 id="指向函数的作用域"><a href="#指向函数的作用域" class="headerlink" title="指向函数的作用域"></a>指向函数的作用域</h4><p>在某种情况下是正确的，但是在其他情况下却是错误的。</p>
<p><strong>this在任何情况下都不指向函数的词法作用域。</strong></p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">var</span> a = <span class="hljs-number">2</span>;</span><br><span class="line">	<span class="hljs-keyword">this</span>.bar();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bar</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.a);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">foo();</span><br></pre></td></tr></table></figure>
<h3 id="调用位置"><a href="#调用位置" class="headerlink" title="调用位置"></a>调用位置</h3><p>调用位置，即函数被调用的位置，可以分析<strong>调用栈</strong>得到。真正的的调用位置，决定了<code>this</code>绑定。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">baz</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-comment">// 当前调用栈是:baz</span></span><br><span class="line">	<span class="hljs-comment">// 因此，当前调用位置是全局作用域</span></span><br><span class="line"></span><br><span class="line">	<span class="hljs-built_in">console</span>.log( <span class="hljs-string">"baz"</span> );</span><br><span class="line">	bar(); <span class="hljs-comment">// &lt;-- bar 的调用位置</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bar</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-comment">// 当前调用栈是 baz -&gt; bar</span></span><br><span class="line">	<span class="hljs-comment">// 因此，当前调用位置在 baz 中</span></span><br><span class="line"></span><br><span class="line">	<span class="hljs-built_in">console</span>.log( <span class="hljs-string">"bar"</span> );</span><br><span class="line">	foo(); <span class="hljs-comment">// &lt;-- foo 的调用位置</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-comment">// 当前调用栈是 baz -&gt; bar -&gt; foo</span></span><br><span class="line">	<span class="hljs-comment">// 因此，当前调用位置在 bar 中</span></span><br><span class="line"></span><br><span class="line">	<span class="hljs-built_in">console</span>.log( <span class="hljs-string">"foo"</span> );</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">baz(); <span class="hljs-comment">// &lt;-- baz 的调用位置 Chrome: anonymous Firefox: global</span></span><br></pre></td></tr></table></figure>
<h3 id="绑定规则"><a href="#绑定规则" class="headerlink" title="绑定规则"></a>绑定规则</h3><h4 id="默认绑定"><a href="#默认绑定" class="headerlink" title="默认绑定"></a>默认绑定</h4><p>最常用的函数调用类型：<strong>独立函数调用</strong>。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.a); <span class="hljs-comment">// this指向全局对象。</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> a = <span class="hljs-number">2</span>;</span><br><span class="line"></span><br><span class="line">foo(); 	<span class="hljs-comment">// 2</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line"><span class="hljs-meta">	"use strict"</span>;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>); <span class="hljs-comment">// this绑定到undefined</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> a = <span class="hljs-number">2</span>;</span><br><span class="line"></span><br><span class="line">foo(); 	<span class="hljs-comment">// TypeError: Cannot read property 'a' of undefined</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.a); <span class="hljs-comment">// this指向全局对象。</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> a = <span class="hljs-number">2</span>;</span><br><span class="line"></span><br><span class="line">(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line"><span class="hljs-meta">	"use strict"</span>;</span><br><span class="line">	foo(); 	<span class="hljs-comment">// 2</span></span><br><span class="line">&#125;)();</span><br></pre></td></tr></table></figure>
<p>通常不会在代码中混合使用<code>strict</code>模式和非<code>strict</code>模式。</p>
<h4 id="隐式绑定"><a href="#隐式绑定" class="headerlink" title="隐式绑定"></a>隐式绑定</h4><p>在一个对象内部包含一个指向函数的属性，通过这个属性间接引用函数，从而把<code>this</code>隐式绑定到这个对象上。</p>
<p>当函数引用有上下文对象时，<strong>隐式绑定</strong>规则会把函数调用中的<code>this</code>绑定到这个上下文对象。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.a); <span class="hljs-comment">// this被绑定到obj</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> obj = &#123;</span><br><span class="line">	a: <span class="hljs-number">2</span>,</span><br><span class="line">	foo: foo</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">obj.foo(); <span class="hljs-comment">// 2</span></span><br></pre></td></tr></table></figure>
<p>对象属性引用链中只有上一层(最后一层)在调用位置中起作用。e.g.:<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.a);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> obj2 = &#123;</span><br><span class="line">	a: <span class="hljs-number">42</span>,</span><br><span class="line">	foo: foo</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> obj1 = &#123;</span><br><span class="line">	a: <span class="hljs-number">2</span>,</span><br><span class="line">	obj2: obj2</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">obj1.obj2.foo(); <span class="hljs-comment">//42</span></span><br></pre></td></tr></table></figure></p>
<p><strong>隐式丢失</strong></p>
<p>丢失绑定对象，应用默认绑定，从而绑定到全局对象或<code>undefined</code>。</p>
<ul>
<li><p>函数引用传递</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.a);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> obj = &#123;</span><br><span class="line">	a: <span class="hljs-number">2</span>,</span><br><span class="line">	foo: foo</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> bar = obj.foo; <span class="hljs-comment">// 函数别名</span></span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> a = <span class="hljs-string">"oops, global"</span>;</span><br><span class="line"></span><br><span class="line">bar(); <span class="hljs-comment">// oops, global</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>传入回调</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.a);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">doFoo</span>(<span class="hljs-params">fn</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-comment">// fn引用的是foo</span></span><br><span class="line"></span><br><span class="line">	fn(); <span class="hljs-comment">// &lt;-- 调用位置</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> obj = &#123;</span><br><span class="line">	a: <span class="hljs-number">2</span>,</span><br><span class="line">	foo: foo</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> a = <span class="hljs-string">"oops, global"</span>;</span><br><span class="line"></span><br><span class="line">doFoo(obj.foo); <span class="hljs-comment">// oops, global</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<h4 id="显式绑定"><a href="#显式绑定" class="headerlink" title="显式绑定"></a>显式绑定</h4><p>在某个对象上强制调用函数，可以使用<code>call(..)</code>和<code>apply(..)</code>。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.a);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> obj = &#123;</span><br><span class="line">	a: <span class="hljs-number">2</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">foo.call(obj); <span class="hljs-comment">// 2</span></span><br></pre></td></tr></table></figure>
<p>如果传入一个原始值(字符串类型/布尔类型/数字类型)来当作<code>this</code>的绑定对象，这个原始值会被转换成相应的对象形式(<code>new String()/new Boolean()/new Number()</code>)。即<strong>装箱</strong>。</p>
<p>显式绑定仍然会出现<strong>丢失绑定</strong>的问题。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.a);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> obj = &#123;</span><br><span class="line">	a: <span class="hljs-number">2</span>,</span><br><span class="line">	foo: foo</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> bar = obj.foo;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> a = <span class="hljs-string">"oops, global"</span>;</span><br><span class="line"></span><br><span class="line">bar(); <span class="hljs-comment">// oops, global</span></span><br></pre></td></tr></table></figure>
<p>使用显式绑定的一个变种可以解决这个问题，称为<strong>硬绑定</strong>。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.a);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> obj = &#123;</span><br><span class="line">	a: <span class="hljs-number">2</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> bar = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	foo.call(obj);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">bar(); <span class="hljs-comment">// 2</span></span><br><span class="line"></span><br><span class="line">bar.call(<span class="hljs-built_in">window</span>); <span class="hljs-comment">// 2</span></span><br></pre></td></tr></table></figure>
<p>由于硬绑定是一种非常常用的模式，所以在ES5中提供了内置的方法<code>Function.prototype.bind</code>，它的用法如下:</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params">something</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.a, something);</span><br><span class="line">	<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.a + something;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> obj = &#123;</span><br><span class="line">	a:<span class="hljs-number">2</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> bar = foo.bind(obj);</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> b = bar(<span class="hljs-number">3</span>); <span class="hljs-comment">// 2 3</span></span><br><span class="line"><span class="hljs-built_in">console</span>.log(b); <span class="hljs-comment">// 5</span></span><br></pre></td></tr></table></figure>
<p><code>bind(..)</code>会返回一个硬编码的新函数，它会把你指定的参数设置为<code>this</code>的上下文并调用原始函数。</p>
<h4 id="new绑定"><a href="#new绑定" class="headerlink" title="new绑定"></a>new绑定</h4><p>在传统的面向类的语言中，“构造函数”是类中的一些特殊方法，使用<code>new</code>初始化类时会被调用。通常形式如下：</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">User user = <span class="hljs-keyword">new</span> User();</span><br></pre></td></tr></table></figure>
<p>在JavaScript中，<code>new</code>的机制和面向类的语言完全不同。构造函数只是一些使用<code>new</code>操作符时被调用的普通函数。它们并不会属于某个类，也不会实例化一个类。</p>
<p>使用<code>new</code>来调用函数，或者说发生构造函数调用时，会自动执行下面的操作。</p>
<ul>
<li>1.创建(或者说构造)一个全新的对象。</li>
<li>2.这个新对象会被执行<strong>[[Prototype]]</strong>连接。</li>
<li>3.这个新对象会绑定到函数调用的this。</li>
<li>4.如果函数没有返回其他对象，那么new表达式中的函数调用会自动返回这个新对象。</li>
</ul>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params">a</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">this</span>.a = a;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> bar = <span class="hljs-keyword">new</span> foo(<span class="hljs-number">2</span>);</span><br><span class="line"><span class="hljs-built_in">console</span>.log(bar.a); <span class="hljs-comment">// 2</span></span><br></pre></td></tr></table></figure>
<h3 id="优先级"><a href="#优先级" class="headerlink" title="优先级"></a>优先级</h3><p>关于<code>this</code>的四条绑定规则，只需要找到函数的调用位置，基本就可以判断该应用哪条规则。但是，有些调用位置可以应用多条规则，这时就必须根据<strong>优先级</strong>来进行判断了。</p>
<p>毫无疑问，<strong>默认绑定</strong>的优先级是最低的。</p>
<ul>
<li>显式绑定 vs 隐式绑定<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.a);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> obj1 = &#123;</span><br><span class="line">	a: <span class="hljs-number">2</span>,</span><br><span class="line">	foo: foo</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> obj2 = &#123;</span><br><span class="line">	a: <span class="hljs-number">3</span>,</span><br><span class="line">	foo: foo</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">obj1.foo(); <span class="hljs-comment">// 2</span></span><br><span class="line">obj2.foo(); <span class="hljs-comment">// 3</span></span><br><span class="line"></span><br><span class="line">obj1.foo.call(obj2); <span class="hljs-comment">// 3</span></span><br><span class="line">obj2.foo.call(obj1); <span class="hljs-comment">// 2</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>显式绑定优先级高于隐式绑定。</p>
<ul>
<li>new绑定 vs 隐式绑定<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params">something</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">this</span>.a = something;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> obj1 = &#123;</span><br><span class="line">	foo: foo</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> obj2 = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">obj1.foo(<span class="hljs-number">2</span>);</span><br><span class="line"><span class="hljs-built_in">console</span>.log(obj1.a); <span class="hljs-comment">// 2</span></span><br><span class="line"></span><br><span class="line">obj1.foo.call(obj2, <span class="hljs-number">3</span>);</span><br><span class="line"><span class="hljs-built_in">console</span>.log(obj2.a); <span class="hljs-comment">// 3</span></span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> bar = <span class="hljs-keyword">new</span> obj1.foo(<span class="hljs-number">4</span>);</span><br><span class="line"><span class="hljs-built_in">console</span>.log(obj1.a); <span class="hljs-comment">// 2</span></span><br><span class="line"><span class="hljs-built_in">console</span>.log(bar.a); <span class="hljs-comment">// 4</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>new绑定优先级高于隐式绑定。</p>
<ul>
<li>new绑定 vs 显式绑定<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params">something</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">this</span>.a = something;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> obj1 = &#123;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> bar = foo.bind(obj1);</span><br><span class="line">bar(<span class="hljs-number">2</span>);</span><br><span class="line"><span class="hljs-built_in">console</span>.log(obj1.a); <span class="hljs-comment">// 2</span></span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> baz = <span class="hljs-keyword">new</span> bar(<span class="hljs-number">3</span>);</span><br><span class="line"><span class="hljs-built_in">console</span>.log(obj1.a); <span class="hljs-comment">// 2</span></span><br><span class="line"><span class="hljs-built_in">console</span>.log(baz.a); <span class="hljs-comment">// 3</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<p><code>bar</code>被硬绑定到<code>obj1</code>上，但是<code>new bar(3)</code>并没有把<code>obj1.a</code>修改为<code>3</code>。相反，<code>new</code>修改了硬绑定调用<code>bar(..)</code>中的<code>this</code>。使用<code>new</code>绑定，得到一个名为<code>baz</code>的新对象，并且<code>baz.a</code>的值是<code>3</code>。</p>
<p><strong>判断this</strong></p>
<ul>
<li><p>1.函数是否在<code>new</code>中调用(<strong>new绑定</strong>)？如果是的话this绑定的是新创建的对象。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> bar = <span class="hljs-keyword">new</span> foo();</span><br></pre></td></tr></table></figure>
</li>
<li><p>2.函数是否通过<code>call</code>、<code>apply</code>(<strong>显式绑定</strong>)或者硬绑定调用？如果是的话，this绑定的是指定的对象。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> bar = foo.call(obj2);</span><br></pre></td></tr></table></figure>
</li>
<li><p>3.函数是否在某个上下文对象中调用(<strong>隐式绑定</strong>)？如果是的话，<code>this</code>绑定的是那个上下文对象。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> bar = obj1.foo();</span><br></pre></td></tr></table></figure>
</li>
<li><p>4.如果都不是的话，使用<strong>默认绑定</strong>。如果在严格模式下，就绑定到<code>undefined</code>，否则绑定到全局对象。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> bar = foo();</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="4-原型"><a href="#4-原型" class="headerlink" title="4. 原型"></a>4. 原型</h2><h2 id="5-异步"><a href="#5-异步" class="headerlink" title="5. 异步"></a>5. 异步</h2><!-- JavaScript程序卸载多个`.js`文件中，这个程序由多个**块**构成。最常见的**块**单位是函数。

**宿主环境**提供一种机制来处理程序中多个块的执行，且执行每块时调用JavaScript引擎，这种机制被称为**事件循环**。

“事件”(代码执行)调度总是由包含它的环境进行。 -->
<p><strong>回调</strong>是JavaScript中最基础的异步模式。</p>
<p>以下代码被称为<strong>回调地狱(callback hell)</strong>，有时也被称为<strong>毁灭金字塔(pyramid of doom)</strong>：<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">listen(<span class="hljs-string">"click"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params">evt</span>) </span>&#123;</span><br><span class="line">	setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">request</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">		ajax(<span class="hljs-string">"http://some.url.1"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">response</span>(<span class="hljs-params">text</span>) </span>&#123;</span><br><span class="line">			<span class="hljs-keyword">if</span> (text == <span class="hljs-string">"hello"</span>) &#123;</span><br><span class="line">				handler(); &#125;</span><br><span class="line">			<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (text == <span class="hljs-string">"world"</span>) &#123;</span><br><span class="line">				request();</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;);</span><br><span class="line">	&#125;, <span class="hljs-number">500</span>) ;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p>
<p>为了更优雅的处理错误，有些API设计提供了<strong>分离回调</strong>：<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">success</span>(<span class="hljs-params">data</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(data);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">failure</span>(<span class="hljs-params">err</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.error(err);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">ajax(<span class="hljs-string">"http://some.url.1"</span>, success, failure);</span><br></pre></td></tr></table></figure></p>
<h1 id="ES6特性"><a href="#ES6特性" class="headerlink" title="ES6特性"></a>ES6特性</h1><h2 id="语法特性"><a href="#语法特性" class="headerlink" title="语法特性"></a>语法特性</h2><h3 id="1-块作用域"><a href="#1-块作用域" class="headerlink" title="1. 块作用域"></a>1. 块作用域</h3><h4 id="let"><a href="#let" class="headerlink" title="let"></a>let</h4><p><code>let</code>可以将变量绑定到所在的任意作用域中(通常是{..}内部)。换句话说，<code>let</code>为其声明的变量隐式的劫持了所在的块作用域。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">10</span>; i++) &#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(i);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(i); <span class="hljs-comment">// ReferenceError: i is not defined</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> t = <span class="hljs-literal">true</span>;</span><br><span class="line"><span class="hljs-keyword">if</span> (t) &#123;</span><br><span class="line">	<span class="hljs-keyword">let</span> a = <span class="hljs-number">3</span>;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(a);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// ReferenceError: a is not defined</span></span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">if</span> (t) &#123;</span><br><span class="line">	&#123; <span class="hljs-comment">// 显式的块</span></span><br><span class="line">		<span class="hljs-keyword">let</span> b = <span class="hljs-number">2</span>;</span><br><span class="line">		<span class="hljs-built_in">console</span>.log(b);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> a = <span class="hljs-number">2</span>;</span><br><span class="line"></span><br><span class="line">&#123;</span><br><span class="line">	<span class="hljs-keyword">let</span> a = <span class="hljs-number">3</span>;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// 3</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// 2</span></span><br></pre></td></tr></table></figure>
<p><strong><code>let</code>声明不会在块作用域中进行提升:</strong><br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// undefined</span></span><br><span class="line">	<span class="hljs-built_in">console</span>.log(b); <span class="hljs-comment">// ReferenceError: c is not defined</span></span><br><span class="line"></span><br><span class="line">	<span class="hljs-keyword">var</span> a;</span><br><span class="line">	<span class="hljs-keyword">let</span> b;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p><strong>垃圾收集:</strong></p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">process</span>(<span class="hljs-params">data</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-comment">// ...</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> someReallyBigData = &#123; .. &#125;;</span><br><span class="line"></span><br><span class="line">process(someReallyBigData);</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> btn = <span class="hljs-built_in">document</span>.getElementById( <span class="hljs-string">"my_button"</span> );</span><br><span class="line"></span><br><span class="line">btn.addEventListener( <span class="hljs-string">"click"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">click</span>(<span class="hljs-params">evt</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"button clicked"</span>);</span><br><span class="line">&#125;, <span class="hljs-comment">/*capturingPhase=*/</span><span class="hljs-literal">false</span> );</span><br></pre></td></tr></table></figure>
<p><code>click</code>函数的点击回调并不需要<code>someReallyBigData</code>变量。理论上这意味着当<code>process(..)</code>执行后，在内存中占用大量空间的数据结构就可以被垃圾回收了。但是，由于<code>click</code>函数形成了一个覆盖整个作用域的闭包，JavaScript引擎极有可能依然保存着这个结构(取决于具体实现)。</p>
<p>块作用域可以打消这种顾虑，可以让引擎清楚地知道没有必要继续保存<code>someReallyBigData</code>了:<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">process</span>(<span class="hljs-params">data</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-comment">// ...</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">// 在这个块中定义的内容可以销毁了!</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="hljs-keyword">let</span> someReallyBigData = &#123; .. &#125;;</span><br><span class="line">	process( someReallyBigData );</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> btn = <span class="hljs-built_in">document</span>.getElementById( <span class="hljs-string">"my_button"</span> );</span><br><span class="line"></span><br><span class="line">btn.addEventListener( <span class="hljs-string">"click"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">click</span>(<span class="hljs-params">evt</span>)</span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"button clicked"</span>);</span><br><span class="line">&#125;, <span class="hljs-comment">/*capturingPhase=*/</span><span class="hljs-literal">false</span> );</span><br></pre></td></tr></table></figure></p>
<p><strong>注意:</strong></p>
<ul>
<li>尽量把<code>let</code>声明放在块的最前面</li>
<li>声明多个变量，建议使用一个<code>let</code><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">let</span> a, b, c;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h4 id="const"><a href="#const" class="headerlink" title="const"></a>const</h4><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">const</span> a = <span class="hljs-number">2</span>;</span><br><span class="line"><span class="hljs-built_in">console</span>.log(a);</span><br><span class="line">a = <span class="hljs-number">3</span>; <span class="hljs-comment">//TypeError</span></span><br></pre></td></tr></table></figure>
<ul>
<li>用于创建常量</li>
<li>常量不是对这个值本身的限制，而是对赋值的那个变量的限制</li>
<li>大写字母+下划线<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">const</span> MAX_VALUE = <span class="hljs-number">10</span>;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h4 id="块作用域函数"><a href="#块作用域函数" class="headerlink" title="块作用域函数"></a>块作用域函数</h4><p><strong>ES6之前<code>condition</code>无论值为什么，<code>bar</code>声明都会被提升，最后一个胜出。</strong></p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">if</span> (condition) &#123;</span><br><span class="line">	<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bar</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">		<span class="hljs-built_in">console</span>.log(<span class="hljs-number">1</span>);</span><br><span class="line">	&#125;</span><br><span class="line">&#125; <span class="hljs-keyword">else</span> &#123;</span><br><span class="line">	<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bar</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">		<span class="hljs-built_in">console</span>.log(<span class="hljs-number">2</span>);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">bar();</span><br></pre></td></tr></table></figure>
<h3 id="2-spread-rest"><a href="#2-spread-rest" class="headerlink" title="2. spread/rest"></a>2. spread/rest</h3><p><strong>新运算符<code>...</code></strong></p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">// spread: 把变量展开为各个独立的值</span></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params">x, y, z</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(x, y, z);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">foo(...[<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]);</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">// [1].concat(a, [5])</span></span><br><span class="line"><span class="hljs-keyword">var</span> a = [<span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>];</span><br><span class="line"><span class="hljs-keyword">var</span> b = [<span class="hljs-number">1</span>, ...a, <span class="hljs-number">5</span>];</span><br><span class="line"><span class="hljs-built_in">console</span>.log(b);</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">// rest: 把一系列值收集到一起成为一个数组</span></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params">x, y, ...z</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(x, y, z);</span><br><span class="line">&#125;</span><br><span class="line">foo(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>);</span><br><span class="line"></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params">...r</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(r);</span><br><span class="line">&#125;</span><br><span class="line">foo(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>);</span><br></pre></td></tr></table></figure>
<p><strong><code>arguments</code>，并不是真正的数组，而是类似数组的对象。已被弃用，不推荐使用。</strong></p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">// 按照新的ES6的行为方式实现</span></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params">...args</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-comment">// args已经是一个真正的数组</span></span><br><span class="line"></span><br><span class="line">	<span class="hljs-comment">// 丢弃args中第一个元素</span></span><br><span class="line">    args.shift();</span><br><span class="line"></span><br><span class="line">	<span class="hljs-comment">// 把整个args作为参数传给console.log(..)</span></span><br><span class="line">    <span class="hljs-built_in">console</span>.log( ...args );</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">// 按照前ES6的老派行为方式实现</span></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bar</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-comment">// 把arguments转换为一个真正的数组</span></span><br><span class="line">	<span class="hljs-keyword">var</span> args = <span class="hljs-built_in">Array</span>.prototype.slice.call( <span class="hljs-built_in">arguments</span> );</span><br><span class="line"></span><br><span class="line">	<span class="hljs-comment">// 在尾端添加几个元素</span></span><br><span class="line">	args.push( <span class="hljs-number">4</span>, <span class="hljs-number">5</span> );</span><br><span class="line"></span><br><span class="line">	<span class="hljs-comment">// 过滤掉奇数</span></span><br><span class="line">	args = args.filter( <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">v</span>)</span>&#123;</span><br><span class="line">		<span class="hljs-keyword">return</span> v % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>;</span><br><span class="line">	&#125; );</span><br><span class="line"></span><br><span class="line">	<span class="hljs-comment">// 把整个args作为参数传给foo(..)</span></span><br><span class="line">	foo.apply( <span class="hljs-literal">null</span>, args );</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">bar( <span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span> ); <span class="hljs-comment">// 2 4</span></span><br></pre></td></tr></table></figure>
<h3 id="3-默认参数值"><a href="#3-默认参数值" class="headerlink" title="3. 默认参数值"></a>3. 默认参数值</h3><h4 id="简单默认值"><a href="#简单默认值" class="headerlink" title="简单默认值"></a>简单默认值</h4><p><strong>ES5中默认值的实现，作用很大，也很危险。</strong></p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params">x, y</span>) </span>&#123;</span><br><span class="line">	x = x || <span class="hljs-number">11</span>;</span><br><span class="line">	y = y || <span class="hljs-number">31</span>;</span><br><span class="line"></span><br><span class="line">	<span class="hljs-comment">// x = (x !== undefined) ? x : 11;</span></span><br><span class="line">	<span class="hljs-comment">// y = (y !== undefined) ? y : 31;</span></span><br><span class="line"></span><br><span class="line">	<span class="hljs-built_in">console</span>.log(x + y);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">foo();</span><br><span class="line">foo(<span class="hljs-number">5</span>, <span class="hljs-number">6</span>);</span><br><span class="line">foo(<span class="hljs-number">5</span>);</span><br><span class="line">foo(<span class="hljs-literal">null</span>, <span class="hljs-number">6</span>);</span><br></pre></td></tr></table></figure>
<ul>
<li>被认为是假的值</li>
</ul>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">foo(<span class="hljs-number">0</span>, <span class="hljs-number">42</span>)</span><br></pre></td></tr></table></figure>
<ul>
<li>省略第一个参数</li>
</ul>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">foo(, <span class="hljs-number">6</span>);</span><br><span class="line"></span><br><span class="line">foo.apply(<span class="hljs-literal">null</span>, [, <span class="hljs-number">6</span>]);</span><br><span class="line"></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params">obj</span>) </span>&#123;</span><br><span class="line">	obj = obj || &#123;&#125;;</span><br><span class="line"></span><br><span class="line">	obj.a = obj.a || <span class="hljs-number">11</span>;</span><br><span class="line">	<span class="hljs-comment">// ..</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>ES6缺失参数赋值</strong><br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params">x = <span class="hljs-number">11</span>, y = <span class="hljs-number">31</span></span>) </span>&#123;</span><br><span class="line">    <span class="hljs-built_in">console</span>.log( x + y );</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">foo();</span><br><span class="line">foo( <span class="hljs-number">5</span>, <span class="hljs-number">6</span> );</span><br><span class="line">foo( <span class="hljs-number">0</span>, <span class="hljs-number">42</span> );</span><br><span class="line">foo( <span class="hljs-number">5</span> );</span><br><span class="line">foo( <span class="hljs-number">5</span>, <span class="hljs-literal">undefined</span> );</span><br><span class="line">foo( <span class="hljs-number">5</span>, <span class="hljs-literal">null</span> );</span><br><span class="line">foo( <span class="hljs-literal">undefined</span>, <span class="hljs-number">6</span> );</span><br><span class="line">foo( <span class="hljs-literal">null</span>, <span class="hljs-number">6</span> );</span><br></pre></td></tr></table></figure></p>
<h4 id="表达式默认值"><a href="#表达式默认值" class="headerlink" title="表达式默认值"></a>表达式默认值</h4><p><strong>函数默认值除了是简单值，可以是任意合法表达式，甚至是函数调用。</strong></p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bar</span>(<span class="hljs-params">val</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log( <span class="hljs-string">"bar called!"</span> );</span><br><span class="line">	<span class="hljs-keyword">return</span> y + val;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params">x = y + <span class="hljs-number">3</span>, z = bar( x </span>)) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(x, z);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> y = <span class="hljs-number">5</span>;</span><br><span class="line">foo(); 	<span class="hljs-comment">// bar called!</span></span><br><span class="line">		<span class="hljs-comment">// 8 13</span></span><br><span class="line"></span><br><span class="line">foo( <span class="hljs-number">10</span> );	<span class="hljs-comment">// bar called!</span></span><br><span class="line">			<span class="hljs-comment">// 10 15</span></span><br><span class="line"></span><br><span class="line">y = <span class="hljs-number">6</span>;</span><br><span class="line">foo( <span class="hljs-literal">undefined</span>, <span class="hljs-number">10</span> ); <span class="hljs-comment">// 9 10</span></span><br></pre></td></tr></table></figure>
<p><strong>默认值表达式中的<code>标识符</code>引用首先匹配到<code>形式参数作用域&#39;(...)&#39;</code>，然后才会搜索外层作用域。</strong></p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">// z已经声明，但未初始化</span></span><br><span class="line"><span class="hljs-keyword">var</span> w = <span class="hljs-number">1</span>, z = <span class="hljs-number">2</span>;</span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params">x = w + <span class="hljs-number">1</span>, y = x + <span class="hljs-number">1</span>, z = z + <span class="hljs-number">1</span></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(x, y, z);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">foo(); <span class="hljs-comment">// ReferenceError</span></span><br></pre></td></tr></table></figure>
<p>默认回调函数</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">dialog</span>(<span class="hljs-params">msg, cb = function(</span>) </span>&#123;&#125;) &#123;</span><br><span class="line">	<span class="hljs-comment">// ..</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">dialog(<span class="hljs-string">'Hello'</span>);</span><br></pre></td></tr></table></figure>
<h3 id="4-对象字面量扩展"><a href="#4-对象字面量扩展" class="headerlink" title="4. 对象字面量扩展"></a>4. 对象字面量扩展</h3><h4 id="简洁属性"><a href="#简洁属性" class="headerlink" title="简洁属性"></a>简洁属性</h4><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> x = <span class="hljs-number">2</span>, y = <span class="hljs-number">3</span>;</span><br><span class="line"><span class="hljs-keyword">var</span> o = &#123; <span class="hljs-attr">x</span>: x, <span class="hljs-attr">y</span>: y &#125;;</span><br></pre></td></tr></table></figure>
<p>对象属性名与<code>词法标识符(变量)</code>同名，则可如下简写:</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> x = <span class="hljs-number">2</span>, y = <span class="hljs-number">3</span>;</span><br><span class="line"><span class="hljs-keyword">var</span> o = &#123; x, y &#125;;</span><br></pre></td></tr></table></figure>
<h4 id="简洁方法"><a href="#简洁方法" class="headerlink" title="简洁方法"></a>简洁方法</h4><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> o = &#123;</span><br><span class="line">	x: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>&#123;&#125;,</span><br><span class="line">	y: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>&#123;&#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> o = &#123;</span><br><span class="line">	x() &#123;&#125;,</span><br><span class="line">	y() &#123;&#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<h4 id="计算属性名"><a href="#计算属性名" class="headerlink" title="计算属性名"></a>计算属性名</h4><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> prefix = <span class="hljs-string">"user_"</span>;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> o = &#123;</span><br><span class="line">	baz: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">..</span>) </span>&#123; .. &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">o[prefix + <span class="hljs-string">"foo"</span>] = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">..</span>) </span>&#123; .. &#125;;</span><br><span class="line">o[prefix + <span class="hljs-string">"bar"</span>] = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">..</span>) </span>&#123; .. &#125;;</span><br><span class="line">o[prefix + <span class="hljs-string">"id"</span>] = <span class="hljs-string">"9527"</span>;</span><br></pre></td></tr></table></figure>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> prefix = <span class="hljs-string">"user_"</span>;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> o = &#123;</span><br><span class="line">	baz: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">..</span>) </span>&#123; .. &#125;,</span><br><span class="line">	[prefix + <span class="hljs-string">"foo"</span>]: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">..</span>) </span>&#123; .. &#125;,</span><br><span class="line">	[prefix + <span class="hljs-string">"bar"</span>]: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">..</span>) </span>&#123; .. &#125;,</span><br><span class="line">	[prefix + <span class="hljs-string">"id"</span>]: <span class="hljs-string">"9527"</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p>此外还有<code>[[Prototype]]</code>的设定，<code>super</code>对象。</p>
<h3 id="5-解构"><a href="#5-解构" class="headerlink" title="5. 解构"></a>5. 解构</h3><p><strong>解构(destructuring)</strong>可以看作是一个<strong>结构化赋值(structured assignment)</strong>方法。</p>
<p>曾经的手动赋值：<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">// 数组</span></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">return</span> [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">// 对象</span></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bar</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">return</span> &#123;</span><br><span class="line">		x: <span class="hljs-number">4</span>,</span><br><span class="line">		y: <span class="hljs-number">5</span>,</span><br><span class="line">		z: <span class="hljs-number">6</span></span><br><span class="line">	&#125;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> tmp = foo(), <span class="hljs-comment">// 临时变量</span></span><br><span class="line">	a = tmp[<span class="hljs-number">0</span>], b = tmp[<span class="hljs-number">1</span>], c = tmp[<span class="hljs-number">2</span>];</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(a, b, c); <span class="hljs-comment">// 1 2 3</span></span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> obj = bar(), <span class="hljs-comment">// 临时变量</span></span><br><span class="line">	x = obj.x, y = obj.y, z = obj.z;</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(x, y, z); <span class="hljs-comment">// 4 5 6</span></span><br></pre></td></tr></table></figure></p>
<p>ES6新增了一个专门语法，专用于<strong>数组解构</strong>和<strong>对象解构</strong>。这个语法消除了前面代码对临时变量的需求，使代码更加简洁。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">// 数组解构</span></span><br><span class="line"><span class="hljs-keyword">var</span> [a, b, c] = foo();</span><br><span class="line"><span class="hljs-built_in">console</span>.log(a, b, c); <span class="hljs-comment">// 1 2 3</span></span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">// 对象解构</span></span><br><span class="line"><span class="hljs-keyword">var</span> &#123; <span class="hljs-attr">x</span>: x, <span class="hljs-attr">y</span>: y, <span class="hljs-attr">z</span>: z &#125; = bar();</span><br><span class="line"><span class="hljs-built_in">console</span>.log(x, y, z); <span class="hljs-comment">// 4 5 6</span></span><br></pre></td></tr></table></figure>
<h4 id="对象属性赋值模式"><a href="#对象属性赋值模式" class="headerlink" title="对象属性赋值模式"></a>对象属性赋值模式</h4><p>如果属性名和要赋值的变量名相同，可以使用简洁属性使得语法更加简短。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> &#123; <span class="hljs-attr">x</span>: x, <span class="hljs-attr">y</span>: y, <span class="hljs-attr">z</span>: z &#125; = bar();</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">// 简洁属性</span></span><br><span class="line"><span class="hljs-keyword">var</span> &#123; x, y, z &#125; = bar();</span><br></pre></td></tr></table></figure>
<p><strong>对于<code>{ x, .. }</code>，缩写语法省略了<code>x:</code>部分。</strong></p>
<p>简短的形式使得代码更简洁，但是更长的的形式支持把属性赋给非同名变量：<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> &#123; <span class="hljs-attr">x</span>: bam, <span class="hljs-attr">y</span>: baz, <span class="hljs-attr">z</span>: bap &#125; = bar();</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(bam, baz, bap); <span class="hljs-comment">// 4 5 6</span></span><br><span class="line"><span class="hljs-built_in">console</span>.log(x, y, z); <span class="hljs-comment">// ReferenceError</span></span><br></pre></td></tr></table></figure></p>
<p>语法模式比较:</p>
<ul>
<li>对象字面值：<code>target: source</code>(<code>target &lt;-- source</code>)</li>
<li>对象解构赋值：<code>source: target</code>(<code>source --&gt; target</code>)</li>
</ul>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> aa = <span class="hljs-number">10</span>, bb = <span class="hljs-number">20</span>;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> o = &#123; <span class="hljs-attr">x</span>: aa, <span class="hljs-attr">y</span>: bb &#125;;</span><br><span class="line"><span class="hljs-keyword">var</span>     &#123; <span class="hljs-attr">x</span>: AA, <span class="hljs-attr">y</span>: BB &#125; = o;</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(AA, BB); <span class="hljs-comment">// 10 20</span></span><br></pre></td></tr></table></figure>
<h4 id="不只是声明"><a href="#不只是声明" class="headerlink" title="不只是声明"></a>不只是声明</h4><p>解构是一个通用的赋值操作，不仅仅是声明。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> a, b, c, x, y, z;</span><br><span class="line"></span><br><span class="line">[a, b, c] = foo();</span><br><span class="line">( &#123; x, y, z &#125; = bar() ); <span class="hljs-comment">// 省略了声明符，必须把整个赋值表达式用(..)括起来</span></span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(a, b, c); <span class="hljs-comment">// 1 2 3</span></span><br><span class="line"><span class="hljs-built_in">console</span>.log(x, y, z); <span class="hljs-comment">// 4 5 6</span></span><br></pre></td></tr></table></figure>
<p>任何合法的赋值表达式都可以用解构赋值。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> o = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">[o.a, o.b, o.c] = foo();</span><br><span class="line">( &#123; <span class="hljs-attr">x</span>: o.x, <span class="hljs-attr">y</span>: o.y, <span class="hljs-attr">z</span>: o.z &#125; = bar() );</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.info(o);</span><br></pre></td></tr></table></figure>
<p>使用计算属性：<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> which = <span class="hljs-string">'x'</span>,</span><br><span class="line">	o = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">( &#123; [which]: o[which] &#125; = bar() );</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(o);</span><br></pre></td></tr></table></figure></p>
<p>不用临时变量<strong>交换两个变量</strong>：<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> x = <span class="hljs-number">10</span>, y = <span class="hljs-number">20</span>;</span><br><span class="line"></span><br><span class="line">[y, x] = [x, y];</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(x, y); <span class="hljs-comment">// 20 10</span></span><br></pre></td></tr></table></figure></p>
<h4 id="重复赋值"><a href="#重复赋值" class="headerlink" title="重复赋值"></a>重复赋值</h4><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> &#123; <span class="hljs-attr">a</span>: X, <span class="hljs-attr">a</span>: Y &#125; = &#123; <span class="hljs-attr">a</span>: <span class="hljs-number">1</span> &#125;;</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(X, Y); <span class="hljs-comment">// 1 1</span></span><br></pre></td></tr></table></figure>
<p>解构子对象/数组属性：</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> &#123; <span class="hljs-attr">a</span>: &#123; <span class="hljs-attr">x</span>: X, <span class="hljs-attr">x</span>: Y &#125;, a &#125; = &#123; <span class="hljs-attr">a</span>: &#123; <span class="hljs-attr">x</span>: <span class="hljs-number">1</span> &#125; &#125;;</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(X, Y);</span><br><span class="line"><span class="hljs-built_in">console</span>.log(a);</span><br><span class="line"></span><br><span class="line">( &#123; <span class="hljs-attr">a</span>: X, <span class="hljs-attr">a</span>: Y, <span class="hljs-attr">a</span>: [Z] &#125; = &#123; <span class="hljs-attr">a</span>: [<span class="hljs-number">1</span>] &#125; );</span><br><span class="line"></span><br><span class="line">X.push(<span class="hljs-number">2</span>);</span><br><span class="line">Y[<span class="hljs-number">0</span>] = <span class="hljs-number">10</span>;</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(X); <span class="hljs-comment">// [10, 2]</span></span><br><span class="line"><span class="hljs-built_in">console</span>.log(Y); <span class="hljs-comment">// [10, 2]</span></span><br><span class="line"><span class="hljs-built_in">console</span>.log(Z); <span class="hljs-comment">// 1</span></span><br></pre></td></tr></table></figure>
<h3 id="6-模板字面量"><a href="#6-模板字面量" class="headerlink" title="6. 模板字面量"></a>6. 模板字面量</h3><p>模板字面量更应该被称为<strong>插入字符串字面量</strong>。</p>
<p>ES6之前的字符串连接方式：<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> name = <span class="hljs-string">"Kyle"</span>;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> greeting = <span class="hljs-string">"Hello "</span> + name + <span class="hljs-string">"!"</span>;</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(greeting); <span class="hljs-comment">// Hello Kyle!</span></span><br><span class="line"><span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">typeof</span> greeting); <span class="hljs-comment">// string</span></span><br></pre></td></tr></table></figure></p>
<p>ES6中的方式：<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> name = <span class="hljs-string">"Kyle"</span>;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> greeting = <span class="hljs-string">`Hello <span class="hljs-subst">$&#123;name&#125;</span>!`</span>;</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log(greeting); <span class="hljs-comment">// Hello Kyle!</span></span><br><span class="line"><span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">typeof</span> greeting); <span class="hljs-comment">// string</span></span><br></pre></td></tr></table></figure></p>
<p>插入字符串字面量的一个优点是它们可以分散在多行:<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> text =</span><br><span class="line">     <span class="hljs-string">`Now is the time for all good men</span></span><br><span class="line"><span class="hljs-string">     to come to the aid of their</span></span><br><span class="line"><span class="hljs-string">     country!`</span>;</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log( text );</span><br></pre></td></tr></table></figure></p>
<h4 id="插入表达式"><a href="#插入表达式" class="headerlink" title="插入表达式"></a>插入表达式</h4><p>在插入字符串字面量的<code>${..}</code>内可以出现任何合法的表达式，包括函数调用、在线函数表<br>达式调用，甚至其他插入字符串字面量!</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">upper</span>(<span class="hljs-params">s</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">return</span> s.toUpperCase();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> who = <span class="hljs-string">"reader"</span>;</span><br><span class="line"><span class="hljs-keyword">var</span> text =</span><br><span class="line">	<span class="hljs-string">`A very <span class="hljs-subst">$&#123;upper( <span class="hljs-string">"warm"</span> )&#125;</span> welcome</span></span><br><span class="line"><span class="hljs-string">	to all of you <span class="hljs-subst">$&#123;upper( <span class="hljs-string">`<span class="hljs-subst">$&#123;who&#125;</span>s`</span> )&#125;</span>!`</span>;</span><br><span class="line"></span><br><span class="line"><span class="hljs-built_in">console</span>.log( text );</span><br></pre></td></tr></table></figure>
<h4 id="标签模板字面量"><a href="#标签模板字面量" class="headerlink" title="标签模板字面量"></a>标签模板字面量</h4><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params">strings, ...values</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log( strings );</span><br><span class="line">	<span class="hljs-built_in">console</span>.log( values );</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> desc = <span class="hljs-string">"awesome"</span>;</span><br><span class="line"></span><br><span class="line">foo<span class="hljs-string">`Everything is <span class="hljs-subst">$&#123;desc&#125;</span>!`</span>; 	<span class="hljs-comment">// ["Everything is ", "!"]</span></span><br><span class="line">								<span class="hljs-comment">// ["awesome"]</span></span><br></pre></td></tr></table></figure>
<h3 id="7-箭头函数"><a href="#7-箭头函数" class="headerlink" title="7. 箭头函数"></a>7. 箭头函数</h3><p>普通函数和箭头函数对比：<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params">x, y</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">return</span> x + y;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">// 对比</span></span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> foo = <span class="hljs-function">(<span class="hljs-params">x, y</span>) =&gt;</span> x + y;</span><br></pre></td></tr></table></figure></p>
<p>不同形式的箭头函数：<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> f1 = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-number">12</span>;</span><br><span class="line"><span class="hljs-keyword">var</span> f2 = <span class="hljs-function"><span class="hljs-params">x</span> =&gt;</span> x * <span class="hljs-number">2</span>;</span><br><span class="line"><span class="hljs-keyword">var</span> f3 = <span class="hljs-function">(<span class="hljs-params">x, y</span>) =&gt;</span> &#123;</span><br><span class="line">	<span class="hljs-keyword">var</span> z = x * <span class="hljs-number">2</span> + y;</span><br><span class="line">	y++;</span><br><span class="line">	x *= <span class="hljs-number">3</span>;</span><br><span class="line">	<span class="hljs-keyword">return</span> (x + y + z) / <span class="hljs-number">2</span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure></p>
<p>箭头函数特点：</p>
<ul>
<li>标识<code>=&gt;</code>前面是参数，后面是函数体</li>
<li>零个或多个参数，需要用<code>( .. )</code>括起来</li>
<li>函数体的表达式多余1个，或者函数体包含非表达式语句的时候需要用<code>{ .. }</code>括起来</li>
<li>如果只有一个表达式，并且省略了<code>{ .. }</code>，则意味着表达式前面有一个隐含的<code>return</code></li>
</ul>
<p>箭头函数不仅仅是更短的语法，而是<code>this</code>。在箭头函数内部，<code>this</code>绑定不是动态的，而是词法的。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-comment">// 返回一个箭头函数</span></span><br><span class="line">	<span class="hljs-keyword">return</span> <span class="hljs-function">(<span class="hljs-params">a</span>) =&gt;</span> &#123;</span><br><span class="line">		<span class="hljs-comment">// this继承自foo()</span></span><br><span class="line">		<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.a);</span><br><span class="line">	&#125;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> obj1 = &#123;</span><br><span class="line">	a: <span class="hljs-number">2</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> obj2 = &#123;</span><br><span class="line">	a: <span class="hljs-number">3</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> bar = foo.call(obj1);</span><br><span class="line">bar.call(obj2); <span class="hljs-comment">// 2， 不是3</span></span><br></pre></td></tr></table></figure>
<p>箭头函数最常用于回调函数中，例如事件处理器或定时器：<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> &#123;</span><br><span class="line">		<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.a);</span><br><span class="line">	&#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> obj = &#123;</span><br><span class="line">	a: <span class="hljs-number">2</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">foo.call(obj); <span class="hljs-comment">// 2</span></span><br></pre></td></tr></table></figure></p>
<p>曾经使用的一种几乎和箭头函数完全一样的模式：<br><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;</span><br><span class="line"></span><br><span class="line">	setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>&#123;</span><br><span class="line">		<span class="hljs-built_in">console</span>.log(self.a);</span><br><span class="line">	&#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> obj = &#123;</span><br><span class="line">	a: <span class="hljs-number">2</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">foo.call(obj); <span class="hljs-comment">// 2</span></span><br></pre></td></tr></table></figure></p>
<h3 id="8-for-of循环"><a href="#8-for-of循环" class="headerlink" title="8. for..of循环"></a>8. for..of循环</h3><p>在<code>for</code>和<code>for..in</code>循环组合起来的基础上，ES6又新增了一个<code>for..of</code>循环，在<strong>迭代器</strong>产生的一系列值上循环。</p>
<p><code>for..of</code>循环的值必须是一个<code>iterable</code>，或者可以转换/封箱到一个<code>iterable</code>对象的值。</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">var</span> a = [<span class="hljs-string">"a"</span>, <span class="hljs-string">"b"</span>, <span class="hljs-string">"c"</span>, <span class="hljs-string">"d"</span>, <span class="hljs-string">"e"</span>];</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> idx <span class="hljs-keyword">in</span> a) &#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(idx); <span class="hljs-comment">// 0 1 2 3 4</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> val <span class="hljs-keyword">of</span> a) &#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(val); <span class="hljs-comment">// a b c d e</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">var</span> b = &#123; <span class="hljs-attr">x</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">z</span>: <span class="hljs-number">3</span> &#125;;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> idx <span class="hljs-keyword">in</span> b) &#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(idx);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">// TypeError: b is not iterable</span></span><br><span class="line"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> val <span class="hljs-keyword">of</span> b) &#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(val);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>JavaScript中默认为<code>iterable</code>的标准内建值包括：</p>
<ul>
<li>Arrays</li>
<li>Strings</li>
<li>Generators</li>
<li>Collections / TypedArrays</li>
</ul>
<p>在原生字符串的字符上迭代：</p>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> c <span class="hljs-keyword">of</span> <span class="hljs-string">"hello"</span>) &#123;</span><br><span class="line">	<span class="hljs-built_in">console</span>.log(c); <span class="hljs-comment">// h e l l o</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>原生字符串值”hello”被强制类型转换/封箱到邓建的<code>String</code>封装对象中。</p>
<h3 id="9-正则表达式"><a href="#9-正则表达式" class="headerlink" title="9. 正则表达式"></a>9. 正则表达式</h3><h3 id="10-数字字面量"><a href="#10-数字字面量" class="headerlink" title="10. 数字字面量"></a>10. 数字字面量</h3><h3 id="11-Unicode"><a href="#11-Unicode" class="headerlink" title="11. Unicode"></a>11. Unicode</h3><h3 id="12-Symbol"><a href="#12-Symbol" class="headerlink" title="12. Symbol"></a>12. Symbol</h3><h2 id="代码组织"><a href="#代码组织" class="headerlink" title="代码组织"></a>代码组织</h2><h3 id="1-迭代器"><a href="#1-迭代器" class="headerlink" title="1. 迭代器"></a>1. 迭代器</h3><h3 id="2-生成器"><a href="#2-生成器" class="headerlink" title="2. 生成器"></a>2. 生成器</h3><h3 id="3-模块"><a href="#3-模块" class="headerlink" title="3. 模块"></a>3. 模块</h3><h3 id="4-类"><a href="#4-类" class="headerlink" title="4. 类"></a>4. 类</h3><h2 id="异步流控制"><a href="#异步流控制" class="headerlink" title="异步流控制"></a>异步流控制</h2><h3 id="1-Promise"><a href="#1-Promise" class="headerlink" title="1. Promise"></a>1. Promise</h3><figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ajax</span>(<span class="hljs-params">url, cb</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-comment">// 建立请求，最终调用cb</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">ajax(<span class="hljs-string">"http://some.url.1"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params">err, contents</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">if</span> (err) &#123;</span><br><span class="line">		<span class="hljs-comment">// 处理错误</span></span><br><span class="line">	&#125; <span class="hljs-keyword">else</span> &#123;</span><br><span class="line">		<span class="hljs-comment">// 处理contents</span></span><br><span class="line">	&#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<figure class="highlight js hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ajax</span>(<span class="hljs-params">url</span>) </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">pr</span>(<span class="hljs-params">resolve, reject</span>) </span>&#123;</span><br><span class="line">		<span class="hljs-comment">// 建立请求，最终调用resolve(..)或reject(..)</span></span><br><span class="line">	&#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">ajax(<span class="hljs-string">"http://some.url.1"</span>).then(</span><br><span class="line">	<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fulfilled</span>(<span class="hljs-params">contents</span>) </span>&#123;</span><br><span class="line">		<span class="hljs-comment">// 处理contents</span></span><br><span class="line">	&#125;,</span><br><span class="line">	<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">rejected</span>(<span class="hljs-params">reason</span>) </span>&#123;</span><br><span class="line">		<span class="hljs-comment">// 处理错误原因</span></span><br><span class="line">	&#125;</span><br><span class="line">);</span><br></pre></td></tr></table></figure>
<h3 id="2-生成器-Promise"><a href="#2-生成器-Promise" class="headerlink" title="2. 生成器 + Promise"></a>2. 生成器 + Promise</h3>
    
    </div>
    
    
</article>





    
    
        
<nav class="pagination is-centered is-rounded" role="navigation" aria-label="pagination">
    <div class="pagination-previous">
        <a href="/page/5/">Prev</a>
    </div>
    <div class="pagination-next is-invisible is-hidden-mobile">
        <a href="/page/7/">Next</a>
    </div>
    <ul class="pagination-list is-hidden-mobile">
        
        <li><a class="pagination-link" href="/">1</a></li>
        
        <li><span class="pagination-ellipsis">&hellip;</span></li>
        
        <li><a class="pagination-link" href="/page/5/">5</a></li>
        
        <li><a class="pagination-link is-current" href="/page/6/">6</a></li>
        
    </ul>
</nav>

    
    </div>
</section>
    <footer class="footer">
    <div class="container">
        <div class="columns content">
            <div class="column is-narrow has-text-centered">
                Copyright &copy; 2019 鬼王&nbsp;
                <!-- Powered by <a href="https://github.com/O70" target="_blank">O70</a> -->
            </div>
            <div class="column is-hidden-mobile"></div>

            
            <div class="column is-narrow">
                <div class="columns is-mobile is-multiline is-centered">
                
                    
                <a class="column is-narrow has-text-black" title="京ICP备19029828号" href="http://www.miitbeian.gov.cn">
                    
                    京ICP备19029828号
                    
                </a>
                
                    
                <a class="column is-narrow has-text-black" title="GitHub" href="https://github.com/O70">
                    
                    GitHub
                    
                </a>
                
                </div>
            </div>
            
            

        </div>
    </div>
</footer>

    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment-with-locales.min.js"></script>

<!-- test if the browser is outdated -->
<div id="outdated">
    <h6>Your browser is out-of-date!</h6>
    <p>Update your browser to view this website correctly. <a id="btnUpdateBrowser" href="http://outdatedbrowser.com/">Update my browser now </a></p>
    <p class="last"><a href="#" id="btnCloseUpdateBrowser" title="Close">&times;</a></p>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/outdated-browser/1.1.5/outdatedbrowser.min.js"></script>
<script>
    $(document).ready(function () {
        // plugin function, place inside DOM ready function
        outdatedBrowser({
            bgColor: '#f25648',
            color: '#ffffff',
            lowerThan: 'flex'
        })
    });
</script>

<script>
    window.FontAwesomeConfig = {
        searchPseudoElements: true
    }
    moment.locale("en-AU");
</script>



<script src="/js/script.js"></script>


    
    <div class="searchbox ins-search">
    <div class="searchbox-mask"></div>
    <div class="searchbox-container ins-search-container">
        <div class="searchbox-input-wrapper">
            <input type="text" class="searchbox-input ins-search-input" placeholder="Type something...">
            <span class="searchbox-close ins-close ins-selectable"><i class="fa fa-times-circle"></i></span>
        </div>
        <div class="searchbox-result-wrapper ins-section-wrapper">
            <div class="ins-section-container"></div>
        </div>
    </div>
</div>
<script>
    (function (window) {
        var INSIGHT_CONFIG = {
            TRANSLATION: {
                POSTS: 'Posts',
                PAGES: 'Pages',
                CATEGORIES: 'Categories',
                TAGS: 'Tags',
                UNTITLED: '(Untitled)',
            },
            CONTENT_URL: '/content.json',
        };
        window.INSIGHT_CONFIG = INSIGHT_CONFIG;
    })(window);
</script>
<script src="/js/insight.js"></script>
    
</body>
</html>
